Merge branch 'master' into beatmap-background-with-storyboard-stopping

This commit is contained in:
Bartłomiej Dach
2022-01-11 21:39:49 +01:00
225 changed files with 2420 additions and 1076 deletions

View File

@ -13,3 +13,5 @@ M:System.Enum.HasFlag(System.Enum);Use osu.Framework.Extensions.EnumExtensions.H
M:Realms.IRealmCollection`1.SubscribeForNotifications`1(Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IRealmCollection<T>,NotificationCallbackDelegate<T>) instead. M:Realms.IRealmCollection`1.SubscribeForNotifications`1(Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IRealmCollection<T>,NotificationCallbackDelegate<T>) instead.
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Linq.IQueryable{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IQueryable<T>,NotificationCallbackDelegate<T>) instead. M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Linq.IQueryable{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IQueryable<T>,NotificationCallbackDelegate<T>) instead.
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Generic.IList{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IList<T>,NotificationCallbackDelegate<T>) instead. M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Generic.IList{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IList<T>,NotificationCallbackDelegate<T>) instead.
M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait. Use Task.WaitSafely() to ensure we avoid deadlocks.
P:System.Threading.Tasks.Task`1.Result;Don't use Task.Result. Use Task.GetResultSafely() to ensure we avoid deadlocks.

View File

@ -51,8 +51,8 @@
<Reference Include="Java.Interop" /> <Reference Include="Java.Interop" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1215.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2022.109.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1225.0" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2022.111.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Transitive Dependencies"> <ItemGroup Label="Transitive Dependencies">
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. --> <!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->

View File

@ -76,7 +76,7 @@ namespace osu.Desktop.Security
private void load(OsuColour colours, NotificationOverlay notificationOverlay) private void load(OsuColour colours, NotificationOverlay notificationOverlay)
{ {
Icon = FontAwesome.Solid.ShieldAlt; Icon = FontAwesome.Solid.ShieldAlt;
IconBackgound.Colour = colours.YellowDark; IconBackground.Colour = colours.YellowDark;
} }
} }
} }

View File

@ -14,7 +14,6 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Catch.Tests namespace osu.Game.Rulesets.Catch.Tests
{ {
[TestFixture] [TestFixture]
[Timeout(10000)]
public class CatchBeatmapConversionTest : BeatmapConversionTest<ConvertValue> public class CatchBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
{ {
protected override string ResourceAssembly => "osu.Game.Rulesets.Catch"; protected override string ResourceAssembly => "osu.Game.Rulesets.Catch";

View File

@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Catch.Tests
} }
[Test] [Test]
public void TestJuicestream() public void TestJuiceStream()
{ {
AddStep("hit juicestream", () => spawnJuiceStream(true)); AddStep("hit juicestream", () => spawnJuiceStream(true));
AddUntilStep("wait for completion", () => playfieldIsEmpty); AddUntilStep("wait for completion", () => playfieldIsEmpty);

View File

@ -37,20 +37,20 @@ namespace osu.Game.Rulesets.Catch.Tests
AddStep("show hyperdash droplet", () => SetContents(_ => createDrawableDroplet(true))); AddStep("show hyperdash droplet", () => SetContents(_ => createDrawableDroplet(true)));
} }
private Drawable createDrawableFruit(int indexInBeatmap, bool hyperdash = false) => private Drawable createDrawableFruit(int indexInBeatmap, bool hyperDash = false) =>
new TestDrawableCatchHitObjectSpecimen(new DrawableFruit(new Fruit new TestDrawableCatchHitObjectSpecimen(new DrawableFruit(new Fruit
{ {
IndexInBeatmap = indexInBeatmap, IndexInBeatmap = indexInBeatmap,
HyperDashBindable = { Value = hyperdash } HyperDashBindable = { Value = hyperDash }
})); }));
private Drawable createDrawableBanana() => private Drawable createDrawableBanana() =>
new TestDrawableCatchHitObjectSpecimen(new DrawableBanana(new Banana())); new TestDrawableCatchHitObjectSpecimen(new DrawableBanana(new Banana()));
private Drawable createDrawableDroplet(bool hyperdash = false) => private Drawable createDrawableDroplet(bool hyperDash = false) =>
new TestDrawableCatchHitObjectSpecimen(new DrawableDroplet(new Droplet new TestDrawableCatchHitObjectSpecimen(new DrawableDroplet(new Droplet
{ {
HyperDashBindable = { Value = hyperdash } HyperDashBindable = { Value = hyperDash }
})); }));
private Drawable createDrawableTinyDroplet() => new TestDrawableCatchHitObjectSpecimen(new DrawableTinyDroplet(new TinyDroplet())); private Drawable createDrawableTinyDroplet() => new TestDrawableCatchHitObjectSpecimen(new DrawableTinyDroplet(new TinyDroplet()));

View File

@ -52,16 +52,25 @@ namespace osu.Game.Rulesets.Catch.Edit
return true; return true;
} }
public override bool HandleFlip(Direction direction) public override bool HandleFlip(Direction direction, bool flipOverOrigin)
{ {
if (SelectedItems.Count == 0)
return false;
// This could be implemented in the future if there's a requirement for it.
if (direction == Direction.Vertical)
return false;
var selectionRange = CatchHitObjectUtils.GetPositionRange(SelectedItems); var selectionRange = CatchHitObjectUtils.GetPositionRange(SelectedItems);
bool changed = false; bool changed = false;
EditorBeatmap.PerformOnSelection(h => EditorBeatmap.PerformOnSelection(h =>
{ {
if (h is CatchHitObject catchObject) if (h is CatchHitObject catchObject)
changed |= handleFlip(selectionRange, catchObject); changed |= handleFlip(selectionRange, catchObject, flipOverOrigin);
}); });
return changed; return changed;
} }
@ -116,7 +125,7 @@ namespace osu.Game.Rulesets.Catch.Edit
return Math.Clamp(deltaX, lowerBound, upperBound); return Math.Clamp(deltaX, lowerBound, upperBound);
} }
private bool handleFlip(PositionRange selectionRange, CatchHitObject hitObject) private bool handleFlip(PositionRange selectionRange, CatchHitObject hitObject, bool flipOverOrigin)
{ {
switch (hitObject) switch (hitObject)
{ {
@ -124,7 +133,7 @@ namespace osu.Game.Rulesets.Catch.Edit
return false; return false;
case JuiceStream juiceStream: case JuiceStream juiceStream:
juiceStream.OriginalX = selectionRange.GetFlippedPosition(juiceStream.OriginalX); juiceStream.OriginalX = getFlippedPosition(juiceStream.OriginalX);
foreach (var point in juiceStream.Path.ControlPoints) foreach (var point in juiceStream.Path.ControlPoints)
point.Position *= new Vector2(-1, 1); point.Position *= new Vector2(-1, 1);
@ -133,9 +142,11 @@ namespace osu.Game.Rulesets.Catch.Edit
return true; return true;
default: default:
hitObject.OriginalX = selectionRange.GetFlippedPosition(hitObject.OriginalX); hitObject.OriginalX = getFlippedPosition(hitObject.OriginalX);
return true; return true;
} }
float getFlippedPosition(float original) => flipOverOrigin ? CatchPlayfield.WIDTH - original : selectionRange.GetFlippedPosition(original);
} }
} }
} }

View File

@ -90,9 +90,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default
.ResizeTo(largeFaint.Size * new Vector2(5, 1), duration, Easing.OutQuint) .ResizeTo(largeFaint.Size * new Vector2(5, 1), duration, Easing.OutQuint)
.FadeOut(duration * 2); .FadeOut(duration * 2);
const float angle_variangle = 15; // should be less than 45 const float angle_variance = 15; // should be less than 45
directionalGlow1.Rotation = StatelessRNG.NextSingle(-angle_variangle, angle_variangle, randomSeed, 4); directionalGlow1.Rotation = StatelessRNG.NextSingle(-angle_variance, angle_variance, randomSeed, 4);
directionalGlow2.Rotation = StatelessRNG.NextSingle(-angle_variangle, angle_variangle, randomSeed, 5); directionalGlow2.Rotation = StatelessRNG.NextSingle(-angle_variance, angle_variance, randomSeed, 5);
this.FadeInFromZero(50).Then().FadeOut(duration, Easing.Out); this.FadeInFromZero(50).Then().FadeOut(duration, Easing.Out);
} }

View File

@ -14,7 +14,6 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Mania.Tests namespace osu.Game.Rulesets.Mania.Tests
{ {
[TestFixture] [TestFixture]
[Timeout(10000)]
public class ManiaBeatmapConversionTest : BeatmapConversionTest<ManiaConvertMapping, ConvertValue> public class ManiaBeatmapConversionTest : BeatmapConversionTest<ManiaConvertMapping, ConvertValue>
{ {
protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; protected override string ResourceAssembly => "osu.Game.Rulesets.Mania";

View File

@ -24,13 +24,13 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
public TestSceneHitExplosion() public TestSceneHitExplosion()
{ {
int runcount = 0; int runCount = 0;
AddRepeatStep("explode", () => AddRepeatStep("explode", () =>
{ {
runcount++; runCount++;
if (runcount % 15 > 12) if (runCount % 15 > 12)
return; return;
int poolIndex = 0; int poolIndex = 0;
@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
{ {
c.Add(hitExplosionPools[poolIndex].Get(e => c.Add(hitExplosionPools[poolIndex].Get(e =>
{ {
e.Apply(new JudgementResult(new HitObject(), runcount % 6 == 0 ? new HoldNoteTickJudgement() : new ManiaJudgement())); e.Apply(new JudgementResult(new HitObject(), runCount % 6 == 0 ? new HoldNoteTickJudgement() : new ManiaJudgement()));
e.Anchor = Anchor.Centre; e.Anchor = Anchor.Centre;
e.Origin = Anchor.Centre; e.Origin = Anchor.Centre;

View File

@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
public override IEnumerable<BeatmapStatistic> GetStatistics() public override IEnumerable<BeatmapStatistic> GetStatistics()
{ {
int notes = HitObjects.Count(s => s is Note); int notes = HitObjects.Count(s => s is Note);
int holdnotes = HitObjects.Count(s => s is HoldNote); int holdNotes = HitObjects.Count(s => s is HoldNote);
return new[] return new[]
{ {
@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
{ {
Name = @"Hold Note Count", Name = @"Hold Note Count",
CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders), CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders),
Content = holdnotes.ToString(), Content = holdNotes.ToString(),
}, },
}; };
} }

View File

@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
/// Mapping of <see cref="HitResult"/> to their corresponding /// Mapping of <see cref="HitResult"/> to their corresponding
/// <see cref="LegacyManiaSkinConfigurationLookups"/> value. /// <see cref="LegacyManiaSkinConfigurationLookups"/> value.
/// </summary> /// </summary>
private static readonly IReadOnlyDictionary<HitResult, LegacyManiaSkinConfigurationLookups> hitresult_mapping private static readonly IReadOnlyDictionary<HitResult, LegacyManiaSkinConfigurationLookups> hit_result_mapping
= new Dictionary<HitResult, LegacyManiaSkinConfigurationLookups> = new Dictionary<HitResult, LegacyManiaSkinConfigurationLookups>
{ {
{ HitResult.Perfect, LegacyManiaSkinConfigurationLookups.Hit300g }, { HitResult.Perfect, LegacyManiaSkinConfigurationLookups.Hit300g },
@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
/// Mapping of <see cref="HitResult"/> to their corresponding /// Mapping of <see cref="HitResult"/> to their corresponding
/// default filenames. /// default filenames.
/// </summary> /// </summary>
private static readonly IReadOnlyDictionary<HitResult, string> default_hitresult_skin_filenames private static readonly IReadOnlyDictionary<HitResult, string> default_hit_result_skin_filenames
= new Dictionary<HitResult, string> = new Dictionary<HitResult, string>
{ {
{ HitResult.Perfect, "mania-hit300g" }, { HitResult.Perfect, "mania-hit300g" },
@ -126,11 +126,11 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
private Drawable getResult(HitResult result) private Drawable getResult(HitResult result)
{ {
if (!hitresult_mapping.ContainsKey(result)) if (!hit_result_mapping.ContainsKey(result))
return null; return null;
string filename = this.GetManiaSkinConfig<string>(hitresult_mapping[result])?.Value string filename = this.GetManiaSkinConfig<string>(hit_result_mapping[result])?.Value
?? default_hitresult_skin_filenames[result]; ?? default_hit_result_skin_filenames[result];
var animation = this.GetAnimation(filename, true, true); var animation = this.GetAnimation(filename, true, true);
return animation == null ? null : new LegacyManiaJudgementPiece(result, animation); return animation == null ? null : new LegacyManiaJudgementPiece(result, animation);

View File

@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.UI
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(IScrollingInfo scrollingInfo) private void load(IScrollingInfo scrollingInfo)
{ {
const float angle_variangle = 15; // should be less than 45 const float angle_variance = 15; // should be less than 45
const float roundness = 80; const float roundness = 80;
const float initial_height = 10; const float initial_height = 10;
@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Mania.UI
Masking = true, Masking = true,
Size = new Vector2(0.01f, initial_height), Size = new Vector2(0.01f, initial_height),
Blending = BlendingParameters.Additive, Blending = BlendingParameters.Additive,
Rotation = RNG.NextSingle(-angle_variangle, angle_variangle), Rotation = RNG.NextSingle(-angle_variance, angle_variance),
EdgeEffect = new EdgeEffectParameters EdgeEffect = new EdgeEffectParameters
{ {
Type = EdgeEffectType.Glow, Type = EdgeEffectType.Glow,
@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Mania.UI
Masking = true, Masking = true,
Size = new Vector2(0.01f, initial_height), Size = new Vector2(0.01f, initial_height),
Blending = BlendingParameters.Additive, Blending = BlendingParameters.Additive,
Rotation = RNG.NextSingle(-angle_variangle, angle_variangle), Rotation = RNG.NextSingle(-angle_variance, angle_variance),
EdgeEffect = new EdgeEffectParameters EdgeEffect = new EdgeEffectParameters
{ {
Type = EdgeEffectType.Glow, Type = EdgeEffectType.Glow,

View File

@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Mania.UI
public override bool Remove(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Remove(h); public override bool Remove(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Remove(h);
public void Add(BarLine barline) => stages.ForEach(s => s.Add(barline)); public void Add(BarLine barLine) => stages.ForEach(s => s.Add(barLine));
/// <summary> /// <summary>
/// Retrieves a column from a screen-space position. /// Retrieves a column from a screen-space position.

View File

@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Mania.UI
public override bool Remove(DrawableHitObject h) => Columns.ElementAt(((ManiaHitObject)h.HitObject).Column - firstColumnIndex).Remove(h); public override bool Remove(DrawableHitObject h) => Columns.ElementAt(((ManiaHitObject)h.HitObject).Column - firstColumnIndex).Remove(h);
public void Add(BarLine barline) => base.Add(new DrawableBarLine(barline)); public void Add(BarLine barLine) => base.Add(new DrawableBarLine(barLine));
internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result) internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result)
{ {

View File

@ -12,7 +12,6 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Osu.Tests namespace osu.Game.Rulesets.Osu.Tests
{ {
[TestFixture] [TestFixture]
[Timeout(10000)]
public class OsuBeatmapConversionTest : BeatmapConversionTest<ConvertValue> public class OsuBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
{ {
protected override string ResourceAssembly => "osu.Game.Rulesets.Osu"; protected override string ResourceAssembly => "osu.Game.Rulesets.Osu";

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -70,8 +70,15 @@ namespace osu.Game.Rulesets.Osu.Difficulty
SliderFactor = values[ATTRIB_ID_SLIDER_FACTOR]; SliderFactor = values[ATTRIB_ID_SLIDER_FACTOR];
} }
// Used implicitly by Newtonsoft.Json to not serialize flashlight property in some cases. #region Newtonsoft.Json implicit ShouldSerialize() methods
// The properties in this region are used implicitly by Newtonsoft.Json to not serialise certain fields in some cases.
// They rely on being named exactly the same as the corresponding fields (casing included) and as such should NOT be renamed
// unless the fields are also renamed.
[UsedImplicitly] [UsedImplicitly]
public bool ShouldSerializeFlashlightRating() => Mods.Any(m => m is ModFlashlight); public bool ShouldSerializeFlashlightRating() => Mods.Any(m => m is ModFlashlight);
#endregion
} }
} }

View File

@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (mods.Any(m => m is OsuModNoFail)) if (mods.Any(m => m is OsuModNoFail))
multiplier *= Math.Max(0.90, 1.0 - 0.02 * effectiveMissCount); multiplier *= Math.Max(0.90, 1.0 - 0.02 * effectiveMissCount);
if (mods.Any(m => m is OsuModSpunOut)) if (mods.Any(m => m is OsuModSpunOut) && totalHits > 0)
multiplier *= 1.0 - Math.Pow((double)Attributes.SpinnerCount / totalHits, 0.85); multiplier *= 1.0 - Math.Pow((double)Attributes.SpinnerCount / totalHits, 0.85);
if (mods.Any(h => h is OsuModRelax)) if (mods.Any(h => h is OsuModRelax))

View File

@ -250,7 +250,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
switch (pathType) switch (pathType)
{ {
case PathType.Catmull: case PathType.Catmull:
return colours.Seafoam; return colours.SeaFoam;
case PathType.Bezier: case PathType.Bezier:
return colours.Pink; return colours.Pink;

View File

@ -10,6 +10,7 @@ using osu.Game.Extensions;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Screens.Edit.Compose.Components;
using osuTK; using osuTK;
@ -84,18 +85,28 @@ namespace osu.Game.Rulesets.Osu.Edit
return true; return true;
} }
public override bool HandleFlip(Direction direction) public override bool HandleFlip(Direction direction, bool flipOverOrigin)
{ {
var hitObjects = selectedMovableObjects; var hitObjects = selectedMovableObjects;
var selectedObjectsQuad = getSurroundingQuad(hitObjects); var flipQuad = flipOverOrigin ? new Quad(0, 0, OsuPlayfield.BASE_SIZE.X, OsuPlayfield.BASE_SIZE.Y) : getSurroundingQuad(hitObjects);
bool didFlip = false;
foreach (var h in hitObjects) foreach (var h in hitObjects)
{ {
h.Position = GetFlippedPosition(direction, selectedObjectsQuad, h.Position); var flippedPosition = GetFlippedPosition(direction, flipQuad, h.Position);
if (!Precision.AlmostEquals(flippedPosition, h.Position))
{
h.Position = flippedPosition;
didFlip = true;
}
if (h is Slider slider) if (h is Slider slider)
{ {
didFlip = true;
foreach (var point in slider.Path.ControlPoints) foreach (var point in slider.Path.ControlPoints)
{ {
point.Position = new Vector2( point.Position = new Vector2(
@ -106,7 +117,7 @@ namespace osu.Game.Rulesets.Osu.Edit
} }
} }
return true; return didFlip;
} }
public override bool HandleScale(Vector2 scale, Anchor reference) public override bool HandleScale(Vector2 scale, Anchor reference)

View File

@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Mods
{ {
public override string Name => "Spun Out"; public override string Name => "Spun Out";
public override string Acronym => "SO"; public override string Acronym => "SO";
public override IconUsage? Icon => OsuIcon.ModSpunout; public override IconUsage? Icon => OsuIcon.ModSpunOut;
public override ModType Type => ModType.Automation; public override ModType Type => ModType.Automation;
public override string Description => @"Spinners will be automatically completed."; public override string Description => @"Spinners will be automatically completed.";
public override double ScoreMultiplier => 0.9; public override double ScoreMultiplier => 0.9;

View File

@ -0,0 +1,52 @@
// 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 osu.Framework.Audio.Track;
using osu.Framework.Graphics;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics.Containers;
#nullable enable
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
internal class KiaiFlashingDrawable : BeatSyncedContainer
{
private readonly Drawable flashingDrawable;
private const float flash_opacity = 0.3f;
public KiaiFlashingDrawable(Func<Drawable?> creationFunc)
{
AutoSizeAxes = Axes.Both;
Children = new[]
{
(creationFunc.Invoke() ?? Empty()).With(d =>
{
d.Anchor = Anchor.Centre;
d.Origin = Anchor.Centre;
}),
flashingDrawable = (creationFunc.Invoke() ?? Empty()).With(d =>
{
d.Anchor = Anchor.Centre;
d.Origin = Anchor.Centre;
d.Alpha = 0;
d.Blending = BlendingParameters.Additive;
})
};
}
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
{
if (!effectPoint.KiaiMode)
return;
flashingDrawable
.FadeTo(flash_opacity)
.Then()
.FadeOut(timingPoint.BeatLength * 0.75f);
}
}
}

View File

@ -1,61 +0,0 @@
// 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.Audio.Track;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics.Containers;
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
internal class KiaiFlashingSprite : BeatSyncedContainer
{
private readonly Sprite mainSprite;
private readonly Sprite flashingSprite;
public Texture Texture
{
set
{
mainSprite.Texture = value;
flashingSprite.Texture = value;
}
}
private const float flash_opacity = 0.3f;
public KiaiFlashingSprite()
{
AutoSizeAxes = Axes.Both;
Children = new Drawable[]
{
mainSprite = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
flashingSprite = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Alpha = 0,
Blending = BlendingParameters.Additive,
}
};
}
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
{
if (!effectPoint.KiaiMode)
return;
flashingSprite
.FadeTo(flash_opacity)
.Then()
.FadeOut(timingPoint.BeatLength * 0.75f);
}
}
}

View File

@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables; 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.Sprites;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
@ -68,13 +69,11 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
// at this point, any further texture fetches should be correctly using the priority source if the base texture was retrieved using it. // at this point, any further texture fetches should be correctly using the priority source if the base texture was retrieved using it.
// the flow above handles the case where a sliderendcircle.png is retrieved from the skin, but sliderendcircleoverlay.png doesn't exist. // the flow above handles the case where a sliderendcircle.png is retrieved from the skin, but sliderendcircleoverlay.png doesn't exist.
// expected behaviour in this scenario is not showing the overlay, rather than using hitcircleoverlay.png (potentially from the default/fall-through skin). // expected behaviour in this scenario is not showing the overlay, rather than using hitcircleoverlay.png (potentially from the default/fall-through skin).
Texture overlayTexture = getTextureWithFallback("overlay");
InternalChildren = new[] InternalChildren = new[]
{ {
hitCircleSprite = new KiaiFlashingSprite hitCircleSprite = new KiaiFlashingDrawable(() => new Sprite { Texture = baseTexture })
{ {
Texture = baseTexture,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
}, },
@ -82,9 +81,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Child = hitCircleOverlay = new KiaiFlashingSprite Child = hitCircleOverlay = new KiaiFlashingDrawable(() => getAnimationWithFallback(@"overlay", 1000 / 2d))
{ {
Texture = overlayTexture,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
}, },
@ -126,6 +124,21 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
return tex ?? skin.GetTexture($"hitcircle{name}"); return tex ?? skin.GetTexture($"hitcircle{name}");
} }
Drawable getAnimationWithFallback(string name, double frameLength)
{
Drawable animation = null;
if (!string.IsNullOrEmpty(priorityLookup))
{
animation = skin.GetAnimation($"{priorityLookup}{name}", true, true, frameLength: frameLength);
if (!allowFallback)
return animation;
}
return animation ?? skin.GetAnimation($"hitcircle{name}", true, true, frameLength: frameLength);
}
} }
protected override void LoadComplete() protected override void LoadComplete()

View File

@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
private BarLine createBarLineAtCurrentTime(bool major = false) private BarLine createBarLineAtCurrentTime(bool major = false)
{ {
var barline = new BarLine var barLine = new BarLine
{ {
Major = major, Major = major,
StartTime = Time.Current + 2000, StartTime = Time.Current + 2000,
@ -92,9 +92,9 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
var cpi = new ControlPointInfo(); var cpi = new ControlPointInfo();
cpi.Add(0, new TimingControlPoint { BeatLength = 500 }); cpi.Add(0, new TimingControlPoint { BeatLength = 500 });
barline.ApplyDefaults(cpi, new BeatmapDifficulty()); barLine.ApplyDefaults(cpi, new BeatmapDifficulty());
return barline; return barLine;
} }
} }
} }

View File

@ -12,7 +12,6 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Taiko.Tests namespace osu.Game.Rulesets.Taiko.Tests
{ {
[TestFixture] [TestFixture]
[Timeout(10000)]
public class TaikoBeatmapConversionTest : BeatmapConversionTest<ConvertValue> public class TaikoBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
{ {
protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko";

View File

@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
public override IEnumerable<BeatmapStatistic> GetStatistics() public override IEnumerable<BeatmapStatistic> GetStatistics()
{ {
int hits = HitObjects.Count(s => s is Hit); int hits = HitObjects.Count(s => s is Hit);
int drumrolls = HitObjects.Count(s => s is DrumRoll); int drumRolls = HitObjects.Count(s => s is DrumRoll);
int swells = HitObjects.Count(s => s is Swell); int swells = HitObjects.Count(s => s is Swell);
return new[] return new[]
@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
{ {
Name = @"Drumroll Count", Name = @"Drumroll Count",
CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders), CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders),
Content = drumrolls.ToString(), Content = drumRolls.ToString(),
}, },
new BeatmapStatistic new BeatmapStatistic
{ {

View File

@ -95,7 +95,6 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.That(decodedAfterEncode, Is.Not.Null); Assert.That(decodedAfterEncode, Is.Not.Null);
Assert.That(decodedAfterEncode.ScoreInfo.User.Username, Is.EqualTo(scoreInfo.User.Username)); Assert.That(decodedAfterEncode.ScoreInfo.User.Username, Is.EqualTo(scoreInfo.User.Username));
Assert.That(decodedAfterEncode.ScoreInfo.BeatmapInfoID, Is.EqualTo(scoreInfo.BeatmapInfoID));
Assert.That(decodedAfterEncode.ScoreInfo.Ruleset, Is.EqualTo(scoreInfo.Ruleset)); Assert.That(decodedAfterEncode.ScoreInfo.Ruleset, Is.EqualTo(scoreInfo.Ruleset));
Assert.That(decodedAfterEncode.ScoreInfo.TotalScore, Is.EqualTo(scoreInfo.TotalScore)); Assert.That(decodedAfterEncode.ScoreInfo.TotalScore, Is.EqualTo(scoreInfo.TotalScore));
Assert.That(decodedAfterEncode.ScoreInfo.MaxCombo, Is.EqualTo(scoreInfo.MaxCombo)); Assert.That(decodedAfterEncode.ScoreInfo.MaxCombo, Is.EqualTo(scoreInfo.MaxCombo));

View File

@ -93,7 +93,7 @@ namespace osu.Game.Tests.Beatmaps.IO
using (var stream = File.OpenRead(tempPath)) using (var stream = File.OpenRead(tempPath))
{ {
importedSet = await manager.Import(new ImportTask(stream, Path.GetFileName(tempPath))); importedSet = await manager.Import(new ImportTask(stream, Path.GetFileName(tempPath)));
ensureLoaded(osu); await ensureLoaded(osu);
} }
Assert.IsTrue(File.Exists(tempPath), "Stream source file somehow went missing"); Assert.IsTrue(File.Exists(tempPath), "Stream source file somehow went missing");
@ -171,7 +171,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp)); var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu); await ensureLoaded(osu);
// but contents doesn't, so existing should still be used. // but contents doesn't, so existing should still be used.
Assert.IsTrue(imported.ID == importedSecondTime.Value.ID); Assert.IsTrue(imported.ID == importedSecondTime.Value.ID);
@ -225,7 +225,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp)); var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu); await ensureLoaded(osu);
// check the newly "imported" beatmap is not the original. // check the newly "imported" beatmap is not the original.
Assert.IsTrue(imported.ID != importedSecondTime.Value.ID); Assert.IsTrue(imported.ID != importedSecondTime.Value.ID);
@ -277,7 +277,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp)); var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu); await ensureLoaded(osu);
// check the newly "imported" beatmap is not the original. // check the newly "imported" beatmap is not the original.
Assert.IsTrue(imported.ID != importedSecondTime.Value.ID); Assert.IsTrue(imported.ID != importedSecondTime.Value.ID);
@ -328,7 +328,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp)); var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu); await ensureLoaded(osu);
// check the newly "imported" beatmap is not the original. // check the newly "imported" beatmap is not the original.
Assert.IsTrue(imported.ID != importedSecondTime.Value.ID); Assert.IsTrue(imported.ID != importedSecondTime.Value.ID);
@ -637,7 +637,7 @@ namespace osu.Game.Tests.Beatmaps.IO
if (!importer.ImportAsync(temp).Wait(10000)) if (!importer.ImportAsync(temp).Wait(10000))
Assert.Fail(@"IPC took too long to send"); Assert.Fail(@"IPC took too long to send");
ensureLoaded(osu); ensureLoaded(osu).WaitSafely();
waitForOrAssert(() => !File.Exists(temp), "Temporary still exists after IPC import", 5000); waitForOrAssert(() => !File.Exists(temp), "Temporary still exists after IPC import", 5000);
} }
@ -659,7 +659,7 @@ namespace osu.Game.Tests.Beatmaps.IO
string temp = TestResources.GetTestBeatmapForImport(); string temp = TestResources.GetTestBeatmapForImport();
using (File.OpenRead(temp)) using (File.OpenRead(temp))
await osu.Dependencies.Get<BeatmapManager>().Import(temp); await osu.Dependencies.Get<BeatmapManager>().Import(temp);
ensureLoaded(osu); await ensureLoaded(osu);
File.Delete(temp); File.Delete(temp);
Assert.IsFalse(File.Exists(temp), "We likely held a read lock on the file when we shouldn't"); Assert.IsFalse(File.Exists(temp), "We likely held a read lock on the file when we shouldn't");
} }
@ -698,7 +698,7 @@ namespace osu.Game.Tests.Beatmaps.IO
await osu.Dependencies.Get<BeatmapManager>().Import(temp); await osu.Dependencies.Get<BeatmapManager>().Import(temp);
ensureLoaded(osu); await ensureLoaded(osu);
} }
finally finally
{ {
@ -741,7 +741,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var imported = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp)); var imported = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu); await ensureLoaded(osu);
Assert.IsFalse(imported.Value.Files.Any(f => f.Filename.Contains("subfolder")), "Files contain common subfolder"); Assert.IsFalse(imported.Value.Files.Any(f => f.Filename.Contains("subfolder")), "Files contain common subfolder");
} }
@ -794,7 +794,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var imported = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp)); var imported = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu); await ensureLoaded(osu);
Assert.IsFalse(imported.Value.Files.Any(f => f.Filename.Contains("__MACOSX")), "Files contain resource fork folder, which should be ignored"); Assert.IsFalse(imported.Value.Files.Any(f => f.Filename.Contains("__MACOSX")), "Files contain resource fork folder, which should be ignored");
Assert.IsFalse(imported.Value.Files.Any(f => f.Filename.Contains("actual_data")), "Files contain common subfolder"); Assert.IsFalse(imported.Value.Files.Any(f => f.Filename.Contains("actual_data")), "Files contain common subfolder");
@ -812,7 +812,7 @@ namespace osu.Game.Tests.Beatmaps.IO
} }
[Test] [Test]
public async Task TestUpdateBeatmapInfo() public void TestUpdateBeatmapInfo()
{ {
using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
{ {
@ -822,7 +822,8 @@ namespace osu.Game.Tests.Beatmaps.IO
var manager = osu.Dependencies.Get<BeatmapManager>(); var manager = osu.Dependencies.Get<BeatmapManager>();
string temp = TestResources.GetTestBeatmapForImport(); string temp = TestResources.GetTestBeatmapForImport();
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
osu.Dependencies.Get<BeatmapManager>().Import(temp).WaitSafely();
// Update via the beatmap, not the beatmap info, to ensure correct linking // Update via the beatmap, not the beatmap info, to ensure correct linking
BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0]; BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0];
@ -842,7 +843,7 @@ namespace osu.Game.Tests.Beatmaps.IO
} }
[Test] [Test]
public async Task TestUpdateBeatmapFile() public void TestUpdateBeatmapFile()
{ {
using (HeadlessGameHost host = new CleanRunHeadlessGameHost()) using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
{ {
@ -852,7 +853,8 @@ namespace osu.Game.Tests.Beatmaps.IO
var manager = osu.Dependencies.Get<BeatmapManager>(); var manager = osu.Dependencies.Get<BeatmapManager>();
string temp = TestResources.GetTestBeatmapForImport(); string temp = TestResources.GetTestBeatmapForImport();
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
osu.Dependencies.Get<BeatmapManager>().Import(temp).WaitSafely();
BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0]; BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0];
@ -976,35 +978,35 @@ namespace osu.Game.Tests.Beatmaps.IO
} }
} }
public static async Task<BeatmapSetInfo> LoadQuickOszIntoOsu(OsuGameBase osu) public static Task<BeatmapSetInfo> LoadQuickOszIntoOsu(OsuGameBase osu) => Task.Factory.StartNew(() =>
{ {
string temp = TestResources.GetQuickTestBeatmapForImport(); string temp = TestResources.GetQuickTestBeatmapForImport();
var manager = osu.Dependencies.Get<BeatmapManager>(); var manager = osu.Dependencies.Get<BeatmapManager>();
var importedSet = await manager.Import(new ImportTask(temp)).ConfigureAwait(false); var importedSet = manager.Import(new ImportTask(temp)).GetResultSafely();
ensureLoaded(osu); ensureLoaded(osu).WaitSafely();
waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000); waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000);
return manager.GetAllUsableBeatmapSets().Find(beatmapSet => beatmapSet.ID == importedSet.Value.ID); return manager.GetAllUsableBeatmapSets().Find(beatmapSet => beatmapSet.ID == importedSet.Value.ID);
} }, TaskCreationOptions.LongRunning);
public static async Task<BeatmapSetInfo> LoadOszIntoOsu(OsuGameBase osu, string path = null, bool virtualTrack = false) public static Task<BeatmapSetInfo> LoadOszIntoOsu(OsuGameBase osu, string path = null, bool virtualTrack = false) => Task.Factory.StartNew(() =>
{ {
string temp = path ?? TestResources.GetTestBeatmapForImport(virtualTrack); string temp = path ?? TestResources.GetTestBeatmapForImport(virtualTrack);
var manager = osu.Dependencies.Get<BeatmapManager>(); var manager = osu.Dependencies.Get<BeatmapManager>();
var importedSet = await manager.Import(new ImportTask(temp)).ConfigureAwait(false); var importedSet = manager.Import(new ImportTask(temp)).GetResultSafely();
ensureLoaded(osu); ensureLoaded(osu).WaitSafely();
waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000); waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000);
return manager.GetAllUsableBeatmapSets().Find(beatmapSet => beatmapSet.ID == importedSet.Value.ID); return manager.GetAllUsableBeatmapSets().Find(beatmapSet => beatmapSet.ID == importedSet.Value.ID);
} }, TaskCreationOptions.LongRunning);
private void deleteBeatmapSet(BeatmapSetInfo imported, OsuGameBase osu) private void deleteBeatmapSet(BeatmapSetInfo imported, OsuGameBase osu)
{ {
@ -1053,7 +1055,7 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.AreEqual(expected, osu.Dependencies.Get<DatabaseContextFactory>().Get().FileInfo.Count(f => f.ReferenceCount == 1)); Assert.AreEqual(expected, osu.Dependencies.Get<DatabaseContextFactory>().Get().FileInfo.Count(f => f.ReferenceCount == 1));
} }
private static void ensureLoaded(OsuGameBase osu, int timeout = 60000) private static Task ensureLoaded(OsuGameBase osu, int timeout = 60000) => Task.Factory.StartNew(() =>
{ {
IEnumerable<BeatmapSetInfo> resultSets = null; IEnumerable<BeatmapSetInfo> resultSets = null;
var store = osu.Dependencies.Get<BeatmapManager>(); var store = osu.Dependencies.Get<BeatmapManager>();
@ -1089,14 +1091,14 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.IsTrue(beatmap?.HitObjects.Any() == true); Assert.IsTrue(beatmap?.HitObjects.Any() == true);
beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap; beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap;
Assert.IsTrue(beatmap?.HitObjects.Any() == true); Assert.IsTrue(beatmap?.HitObjects.Any() == true);
} }, TaskCreationOptions.LongRunning);
private static void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000) private static void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
{ {
Task task = Task.Run(() => Task task = Task.Factory.StartNew(() =>
{ {
while (!result()) Thread.Sleep(200); while (!result()) Thread.Sleep(200);
}); }, TaskCreationOptions.LongRunning);
Assert.IsTrue(task.Wait(timeout), failureMessage); Assert.IsTrue(task.Wait(timeout), failureMessage);
} }

View File

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets; using osu.Game.Rulesets;
@ -32,7 +33,7 @@ namespace osu.Game.Tests.Beatmaps
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuGameBase osu) private void load(OsuGameBase osu)
{ {
importedSet = ImportBeatmapTest.LoadQuickOszIntoOsu(osu).Result; importedSet = ImportBeatmapTest.LoadQuickOszIntoOsu(osu).GetResultSafely();
} }
[SetUpSteps] [SetUpSteps]

View File

@ -9,6 +9,21 @@ namespace osu.Game.Tests.Chat
[TestFixture] [TestFixture]
public class MessageFormatterTests public class MessageFormatterTests
{ {
private string originalWebsiteRootUrl;
[OneTimeSetUp]
public void OneTimeSetUp()
{
originalWebsiteRootUrl = MessageFormatter.WebsiteRootUrl;
MessageFormatter.WebsiteRootUrl = "dev.ppy.sh";
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
MessageFormatter.WebsiteRootUrl = originalWebsiteRootUrl;
}
[Test] [Test]
public void TestBareLink() public void TestBareLink()
{ {
@ -32,8 +47,6 @@ namespace osu.Game.Tests.Chat
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/discussions/123", "https://dev.ppy.sh/beatmapsets/discussions/123")] [TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/discussions/123", "https://dev.ppy.sh/beatmapsets/discussions/123")]
public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link) public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link)
{ {
MessageFormatter.WebsiteRootUrl = "dev.ppy.sh";
Message result = MessageFormatter.FormatMessage(new Message { Content = link }); Message result = MessageFormatter.FormatMessage(new Message { Content = link });
Assert.AreEqual(result.Content, result.DisplayContent); Assert.AreEqual(result.Content, result.DisplayContent);
@ -47,7 +60,10 @@ namespace osu.Game.Tests.Chat
[Test] [Test]
public void TestMultipleComplexLinks() public void TestMultipleComplexLinks()
{ {
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a http://test.io/link#fragment. (see https://twitter.com). Also, This string should not be altered. http://example.com/" }); Message result = MessageFormatter.FormatMessage(new Message
{
Content = "This is a http://test.io/link#fragment. (see https://twitter.com). Also, This string should not be altered. http://example.com/"
});
Assert.AreEqual(result.Content, result.DisplayContent); Assert.AreEqual(result.Content, result.DisplayContent);
Assert.AreEqual(3, result.Links.Count); Assert.AreEqual(3, result.Links.Count);
@ -104,7 +120,7 @@ namespace osu.Game.Tests.Chat
Assert.AreEqual("This is a Wiki Link.", result.DisplayContent); Assert.AreEqual("This is a Wiki Link.", result.DisplayContent);
Assert.AreEqual(1, result.Links.Count); Assert.AreEqual(1, result.Links.Count);
Assert.AreEqual("https://osu.ppy.sh/wiki/Wiki Link", result.Links[0].Url); Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
Assert.AreEqual(10, result.Links[0].Index); Assert.AreEqual(10, result.Links[0].Index);
Assert.AreEqual(9, result.Links[0].Length); Assert.AreEqual(9, result.Links[0].Length);
} }
@ -117,15 +133,15 @@ namespace osu.Game.Tests.Chat
Assert.AreEqual("This is a Wiki Link Wiki:LinkWiki.Link.", result.DisplayContent); Assert.AreEqual("This is a Wiki Link Wiki:LinkWiki.Link.", result.DisplayContent);
Assert.AreEqual(3, result.Links.Count); Assert.AreEqual(3, result.Links.Count);
Assert.AreEqual("https://osu.ppy.sh/wiki/Wiki Link", result.Links[0].Url); Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
Assert.AreEqual(10, result.Links[0].Index); Assert.AreEqual(10, result.Links[0].Index);
Assert.AreEqual(9, result.Links[0].Length); Assert.AreEqual(9, result.Links[0].Length);
Assert.AreEqual("https://osu.ppy.sh/wiki/Wiki:Link", result.Links[1].Url); Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki:Link", result.Links[1].Url);
Assert.AreEqual(20, result.Links[1].Index); Assert.AreEqual(20, result.Links[1].Index);
Assert.AreEqual(9, result.Links[1].Length); Assert.AreEqual(9, result.Links[1].Length);
Assert.AreEqual("https://osu.ppy.sh/wiki/Wiki.Link", result.Links[2].Url); Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki.Link", result.Links[2].Url);
Assert.AreEqual(29, result.Links[2].Index); Assert.AreEqual(29, result.Links[2].Index);
Assert.AreEqual(9, result.Links[2].Length); Assert.AreEqual(9, result.Links[2].Length);
} }
@ -445,12 +461,15 @@ namespace osu.Game.Tests.Chat
[Test] [Test]
public void TestLinkComplex() public void TestLinkComplex()
{ {
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a [http://www.simple-test.com simple test] with some [traps] and [[wiki links]]. Don't forget to visit https://osu.ppy.sh (now!)[http://google.com]\uD83D\uDE12" }); Message result = MessageFormatter.FormatMessage(new Message
{
Content = "This is a [http://www.simple-test.com simple test] with some [traps] and [[wiki links]]. Don't forget to visit https://osu.ppy.sh (now!)[http://google.com]\uD83D\uDE12"
});
Assert.AreEqual("This is a simple test with some [traps] and wiki links. Don't forget to visit https://osu.ppy.sh now!\0\0\0", result.DisplayContent); Assert.AreEqual("This is a simple test with some [traps] and wiki links. Don't forget to visit https://osu.ppy.sh now!\0\0\0", result.DisplayContent);
Assert.AreEqual(5, result.Links.Count); Assert.AreEqual(5, result.Links.Count);
Link f = result.Links.Find(l => l.Url == "https://osu.ppy.sh/wiki/wiki links"); Link f = result.Links.Find(l => l.Url == "https://dev.ppy.sh/wiki/wiki links");
Assert.That(f, Is.Not.Null); Assert.That(f, Is.Not.Null);
Assert.AreEqual(44, f.Index); Assert.AreEqual(44, f.Index);
Assert.AreEqual(10, f.Length); Assert.AreEqual(10, f.Length);
@ -514,8 +533,6 @@ namespace osu.Game.Tests.Chat
[TestCase("https://dev.ppy.sh/home/changelog/lazer/2021.1012", "lazer/2021.1012")] [TestCase("https://dev.ppy.sh/home/changelog/lazer/2021.1012", "lazer/2021.1012")]
public void TestChangelogLinks(string link, string expectedArg) public void TestChangelogLinks(string link, string expectedArg)
{ {
MessageFormatter.WebsiteRootUrl = "dev.ppy.sh";
LinkDetails result = MessageFormatter.GetLinkDetails(link); LinkDetails result = MessageFormatter.GetLinkDetails(link);
Assert.AreEqual(LinkAction.OpenChangelog, result.Action); Assert.AreEqual(LinkAction.OpenChangelog, result.Action);

View File

@ -6,6 +6,7 @@ using System.IO;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Tests.Resources; using osu.Game.Tests.Resources;
@ -179,7 +180,7 @@ namespace osu.Game.Tests.Collections.IO
{ {
// intentionally spin this up on a separate task to avoid disposal deadlocks. // intentionally spin this up on a separate task to avoid disposal deadlocks.
// see https://github.com/EventStore/EventStore/issues/1179 // see https://github.com/EventStore/EventStore/issues/1179
await Task.Run(() => osu.CollectionManager.Import(stream).Wait()); await Task.Factory.StartNew(() => osu.CollectionManager.Import(stream).WaitSafely(), TaskCreationOptions.LongRunning);
} }
} }
} }

View File

@ -6,6 +6,7 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Models; using osu.Game.Models;
@ -104,7 +105,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory); liveBeatmap = beatmap.ToLive(realmFactory);
} }
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait(); }, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null); Debug.Assert(liveBeatmap != null);
@ -115,7 +116,7 @@ namespace osu.Game.Tests.Database
Assert.IsTrue(beatmap.IsValid); Assert.IsTrue(beatmap.IsValid);
Assert.IsFalse(beatmap.Hidden); Assert.IsFalse(beatmap.Hidden);
}); });
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait(); }, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
}); });
} }
@ -133,7 +134,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory); liveBeatmap = beatmap.ToLive(realmFactory);
} }
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait(); }, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null); Debug.Assert(liveBeatmap != null);
@ -141,7 +142,7 @@ namespace osu.Game.Tests.Database
{ {
liveBeatmap.PerformWrite(beatmap => { beatmap.Hidden = true; }); liveBeatmap.PerformWrite(beatmap => { beatmap.Hidden = true; });
liveBeatmap.PerformRead(beatmap => { Assert.IsTrue(beatmap.Hidden); }); liveBeatmap.PerformRead(beatmap => { Assert.IsTrue(beatmap.Hidden); });
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait(); }, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
}); });
} }
@ -175,7 +176,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory); liveBeatmap = beatmap.ToLive(realmFactory);
} }
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait(); }, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null); Debug.Assert(liveBeatmap != null);
@ -195,7 +196,7 @@ namespace osu.Game.Tests.Database
var __ = liveBeatmap.Value; var __ = liveBeatmap.Value;
}); });
} }
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait(); }, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
}); });
} }
@ -213,7 +214,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory); liveBeatmap = beatmap.ToLive(realmFactory);
} }
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait(); }, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null); Debug.Assert(liveBeatmap != null);
@ -223,7 +224,7 @@ namespace osu.Game.Tests.Database
{ {
var unused = liveBeatmap.Value; var unused = liveBeatmap.Value;
}); });
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait(); }, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
}); });
} }
@ -252,7 +253,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory); liveBeatmap = beatmap.ToLive(realmFactory);
} }
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait(); }, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null); Debug.Assert(liveBeatmap != null);

View File

@ -40,80 +40,80 @@ namespace osu.Game.Tests.Editing.Checks
[Test] [Test]
public void TestNormalControlPointVolume() public void TestNormalControlPointVolume()
{ {
var hitcircle = new HitCircle var hitCircle = new HitCircle
{ {
StartTime = 0, StartTime = 0,
Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) }
}; };
hitcircle.ApplyDefaults(cpi, new BeatmapDifficulty()); hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty());
assertOk(new List<HitObject> { hitcircle }); assertOk(new List<HitObject> { hitCircle });
} }
[Test] [Test]
public void TestLowControlPointVolume() public void TestLowControlPointVolume()
{ {
var hitcircle = new HitCircle var hitCircle = new HitCircle
{ {
StartTime = 1000, StartTime = 1000,
Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) }
}; };
hitcircle.ApplyDefaults(cpi, new BeatmapDifficulty()); hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty());
assertLowVolume(new List<HitObject> { hitcircle }); assertLowVolume(new List<HitObject> { hitCircle });
} }
[Test] [Test]
public void TestMutedControlPointVolume() public void TestMutedControlPointVolume()
{ {
var hitcircle = new HitCircle var hitCircle = new HitCircle
{ {
StartTime = 2000, StartTime = 2000,
Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) }
}; };
hitcircle.ApplyDefaults(cpi, new BeatmapDifficulty()); hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty());
assertMuted(new List<HitObject> { hitcircle }); assertMuted(new List<HitObject> { hitCircle });
} }
[Test] [Test]
public void TestNormalSampleVolume() public void TestNormalSampleVolume()
{ {
// The sample volume should take precedence over the control point volume. // The sample volume should take precedence over the control point volume.
var hitcircle = new HitCircle var hitCircle = new HitCircle
{ {
StartTime = 2000, StartTime = 2000,
Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_regular) } Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_regular) }
}; };
hitcircle.ApplyDefaults(cpi, new BeatmapDifficulty()); hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty());
assertOk(new List<HitObject> { hitcircle }); assertOk(new List<HitObject> { hitCircle });
} }
[Test] [Test]
public void TestLowSampleVolume() public void TestLowSampleVolume()
{ {
var hitcircle = new HitCircle var hitCircle = new HitCircle
{ {
StartTime = 2000, StartTime = 2000,
Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_low) } Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_low) }
}; };
hitcircle.ApplyDefaults(cpi, new BeatmapDifficulty()); hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty());
assertLowVolume(new List<HitObject> { hitcircle }); assertLowVolume(new List<HitObject> { hitCircle });
} }
[Test] [Test]
public void TestMutedSampleVolume() public void TestMutedSampleVolume()
{ {
var hitcircle = new HitCircle var hitCircle = new HitCircle
{ {
StartTime = 0, StartTime = 0,
Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_muted) } Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_muted) }
}; };
hitcircle.ApplyDefaults(cpi, new BeatmapDifficulty()); hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty());
assertMuted(new List<HitObject> { hitcircle }); assertMuted(new List<HitObject> { hitCircle });
} }
[Test] [Test]

View File

@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game.Collections; using osu.Game.Collections;
using osu.Game.Tests.Resources; using osu.Game.Tests.Resources;
@ -58,7 +59,7 @@ namespace osu.Game.Tests
{ {
// Beatmap must be imported before the collection manager is loaded. // Beatmap must be imported before the collection manager is loaded.
if (withBeatmap) if (withBeatmap)
BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).Wait(); BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).WaitSafely();
AddInternal(CollectionManager = new CollectionManager(Storage)); AddInternal(CollectionManager = new CollectionManager(Storage));
} }

View File

@ -34,20 +34,20 @@ namespace osu.Game.Tests.Mods
var mod3 = new OsuModDoubleTime { SpeedChange = { Value = 1.26 } }; var mod3 = new OsuModDoubleTime { SpeedChange = { Value = 1.26 } };
var doubleConvertedMod1 = new APIMod(mod1).ToMod(ruleset); var doubleConvertedMod1 = new APIMod(mod1).ToMod(ruleset);
var doulbeConvertedMod2 = new APIMod(mod2).ToMod(ruleset); var doubleConvertedMod2 = new APIMod(mod2).ToMod(ruleset);
var doulbeConvertedMod3 = new APIMod(mod3).ToMod(ruleset); var doubleConvertedMod3 = new APIMod(mod3).ToMod(ruleset);
Assert.That(mod1, Is.Not.EqualTo(mod2)); Assert.That(mod1, Is.Not.EqualTo(mod2));
Assert.That(doubleConvertedMod1, Is.Not.EqualTo(doulbeConvertedMod2)); Assert.That(doubleConvertedMod1, Is.Not.EqualTo(doubleConvertedMod2));
Assert.That(mod2, Is.EqualTo(mod2)); Assert.That(mod2, Is.EqualTo(mod2));
Assert.That(doulbeConvertedMod2, Is.EqualTo(doulbeConvertedMod2)); Assert.That(doubleConvertedMod2, Is.EqualTo(doubleConvertedMod2));
Assert.That(mod2, Is.EqualTo(mod3)); Assert.That(mod2, Is.EqualTo(mod3));
Assert.That(doulbeConvertedMod2, Is.EqualTo(doulbeConvertedMod3)); Assert.That(doubleConvertedMod2, Is.EqualTo(doubleConvertedMod3));
Assert.That(mod3, Is.EqualTo(mod2)); Assert.That(mod3, Is.EqualTo(mod2));
Assert.That(doulbeConvertedMod3, Is.EqualTo(doulbeConvertedMod2)); Assert.That(doubleConvertedMod3, Is.EqualTo(doubleConvertedMod2));
} }
} }
} }

View File

@ -16,7 +16,8 @@ namespace osu.Game.Tests.NonVisual.Filtering
{ {
private BeatmapInfo getExampleBeatmap() => new BeatmapInfo private BeatmapInfo getExampleBeatmap() => new BeatmapInfo
{ {
Ruleset = new RulesetInfo { OnlineID = 5 }, Ruleset = new RulesetInfo { OnlineID = 0 },
RulesetID = 0,
StarRating = 4.0d, StarRating = 4.0d,
BaseDifficulty = new BeatmapDifficulty BaseDifficulty = new BeatmapDifficulty
{ {

View File

@ -4,6 +4,7 @@
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Game.Utils; using osu.Game.Utils;
namespace osu.Game.Tests.NonVisual namespace osu.Game.Tests.NonVisual
@ -42,9 +43,9 @@ namespace osu.Game.Tests.NonVisual
await Task.WhenAll(task1.task, task2.task, task3.task); await Task.WhenAll(task1.task, task2.task, task3.task);
Assert.That(task1.task.Result, Is.EqualTo(1)); Assert.That(task1.task.GetResultSafely(), Is.EqualTo(1));
Assert.That(task2.task.Result, Is.EqualTo(2)); Assert.That(task2.task.GetResultSafely(), Is.EqualTo(2));
Assert.That(task3.task.Result, Is.EqualTo(3)); Assert.That(task3.task.GetResultSafely(), Is.EqualTo(3));
} }
[Test] [Test]
@ -68,9 +69,9 @@ namespace osu.Game.Tests.NonVisual
// Wait on both tasks. // Wait on both tasks.
await Task.WhenAll(task1.task, task3.task); await Task.WhenAll(task1.task, task3.task);
Assert.That(task1.task.Result, Is.EqualTo(1)); Assert.That(task1.task.GetResultSafely(), Is.EqualTo(1));
Assert.That(task2.task.IsCompleted, Is.False); Assert.That(task2.task.IsCompleted, Is.False);
Assert.That(task3.task.Result, Is.EqualTo(2)); Assert.That(task3.task.GetResultSafely(), Is.EqualTo(2));
} }
[Test] [Test]

View File

@ -39,7 +39,7 @@ namespace osu.Game.Tests.Online
} }
[Test] [Test]
public void TestSerialiseUnionFailsWithSingalR() public void TestSerialiseUnionFailsWithSignalR()
{ {
var state = new TeamVersusUserState(); var state = new TeamVersusUserState();

View File

@ -100,7 +100,7 @@ namespace osu.Game.Tests.Online
public void TestTrackerRespectsSoftDeleting() public void TestTrackerRespectsSoftDeleting()
{ {
AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true)); AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true));
AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).Wait()); AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).WaitSafely());
addAvailabilityCheckStep("state locally available", BeatmapAvailability.LocallyAvailable); addAvailabilityCheckStep("state locally available", BeatmapAvailability.LocallyAvailable);
AddStep("delete beatmap", () => beatmaps.Delete(beatmaps.QueryBeatmapSet(b => b.OnlineID == testBeatmapSet.OnlineID))); AddStep("delete beatmap", () => beatmaps.Delete(beatmaps.QueryBeatmapSet(b => b.OnlineID == testBeatmapSet.OnlineID)));
@ -114,12 +114,12 @@ namespace osu.Game.Tests.Online
public void TestTrackerRespectsChecksum() public void TestTrackerRespectsChecksum()
{ {
AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true)); AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true));
AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).Wait()); AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).WaitSafely());
addAvailabilityCheckStep("initially locally available", BeatmapAvailability.LocallyAvailable); addAvailabilityCheckStep("initially locally available", BeatmapAvailability.LocallyAvailable);
AddStep("import altered beatmap", () => AddStep("import altered beatmap", () =>
{ {
beatmaps.Import(TestResources.GetTestBeatmapForImport(true)).Wait(); beatmaps.Import(TestResources.GetTestBeatmapForImport(true)).WaitSafely();
}); });
addAvailabilityCheckStep("state not downloaded", BeatmapAvailability.NotDownloaded); addAvailabilityCheckStep("state not downloaded", BeatmapAvailability.NotDownloaded);
@ -129,7 +129,7 @@ namespace osu.Game.Tests.Online
}); });
addAvailabilityCheckStep("state not downloaded as well", BeatmapAvailability.NotDownloaded); addAvailabilityCheckStep("state not downloaded as well", BeatmapAvailability.NotDownloaded);
AddStep("reimport original beatmap", () => beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait()); AddStep("reimport original beatmap", () => beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely());
addAvailabilityCheckStep("locally available after re-import", BeatmapAvailability.LocallyAvailable); addAvailabilityCheckStep("locally available after re-import", BeatmapAvailability.LocallyAvailable);
} }

View File

@ -8,6 +8,7 @@ using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.IO; using osu.Game.IO;
@ -187,7 +188,7 @@ namespace osu.Game.Tests.Skins.IO
var imported = skinManager.Import(new ImportTask(exportStream, "exported.osk")); var imported = skinManager.Import(new ImportTask(exportStream, "exported.osk"));
imported.Result.PerformRead(s => imported.GetResultSafely().PerformRead(s =>
{ {
Assert.IsFalse(s.Protected); Assert.IsFalse(s.Protected);
Assert.AreNotEqual(originalSkinId, s.ID); Assert.AreNotEqual(originalSkinId, s.ID);
@ -222,7 +223,7 @@ namespace osu.Game.Tests.Skins.IO
var imported = skinManager.Import(new ImportTask(exportStream, "exported.osk")); var imported = skinManager.Import(new ImportTask(exportStream, "exported.osk"));
imported.Result.PerformRead(s => imported.GetResultSafely().PerformRead(s =>
{ {
Assert.IsFalse(s.Protected); Assert.IsFalse(s.Protected);
Assert.AreNotEqual(originalSkinId, s.ID); Assert.AreNotEqual(originalSkinId, s.ID);

View File

@ -4,6 +4,7 @@
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
using osu.Framework.Extensions;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Audio; using osu.Game.Audio;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -24,7 +25,7 @@ namespace osu.Game.Tests.Skins
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
var imported = beatmaps.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-beatmap.osz"))).Result; var imported = beatmaps.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-beatmap.osz"))).GetResultSafely();
beatmap = beatmaps.GetWorkingBeatmap(imported.Value.Beatmaps[0]); beatmap = beatmaps.GetWorkingBeatmap(imported.Value.Beatmaps[0]);
beatmap.LoadTrack(); beatmap.LoadTrack();
} }

View File

@ -3,6 +3,7 @@
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Audio; using osu.Game.Audio;
using osu.Game.IO.Archives; using osu.Game.IO.Archives;
@ -23,7 +24,7 @@ namespace osu.Game.Tests.Skins
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
var imported = skins.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-skin.osk"))).Result; var imported = skins.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-skin.osk"))).GetResultSafely();
skin = imported.PerformRead(skinInfo => skins.GetSkin(skinInfo)); skin = imported.PerformRead(skinInfo => skins.GetSkin(skinInfo));
} }

View File

@ -7,12 +7,14 @@ using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Framework.Input.States; using osu.Framework.Input.States;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Utils;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Graphics; using osu.Game.Graphics;
@ -49,7 +51,7 @@ namespace osu.Game.Tests.Visual.Background
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(new OsuConfigManager(LocalStorage)); Dependencies.Cache(new OsuConfigManager(LocalStorage));
manager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); manager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
Beatmap.SetDefault(); Beatmap.SetDefault();
} }
@ -322,7 +324,7 @@ namespace osu.Game.Tests.Visual.Background
public bool IsBackgroundUndimmed() => background.CurrentColour == Color4.White; public bool IsBackgroundUndimmed() => background.CurrentColour == Color4.White;
public bool IsUserBlurApplied() => background.CurrentBlur == new Vector2((float)BlurLevel.Value * BackgroundScreenBeatmap.USER_BLUR_FACTOR); public bool IsUserBlurApplied() => Precision.AlmostEquals(background.CurrentBlur, new Vector2((float)BlurLevel.Value * BackgroundScreenBeatmap.USER_BLUR_FACTOR), 0.1f);
public bool IsUserBlurDisabled() => background.CurrentBlur == new Vector2(0); public bool IsUserBlurDisabled() => background.CurrentBlur == new Vector2(0);
@ -330,9 +332,9 @@ namespace osu.Game.Tests.Visual.Background
public bool IsBackgroundVisible() => background.CurrentAlpha == 1; public bool IsBackgroundVisible() => background.CurrentAlpha == 1;
public bool IsBackgroundBlur() => background.CurrentBlur == new Vector2(BACKGROUND_BLUR); public bool IsBackgroundBlur() => Precision.AlmostEquals(background.CurrentBlur, new Vector2(BACKGROUND_BLUR), 0.1f);
public bool CheckBackgroundBlur(Vector2 expected) => background.CurrentBlur == expected; public bool CheckBackgroundBlur(Vector2 expected) => Precision.AlmostEquals(background.CurrentBlur, expected, 0.1f);
/// <summary> /// <summary>
/// Make sure every time a screen gets pushed, the background doesn't get replaced /// Make sure every time a screen gets pushed, the background doesn't get replaced

View File

@ -4,6 +4,7 @@
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.UserInterface;
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.Collections
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory)); Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, Resources, host, Beatmap.Default));
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
base.Content.AddRange(new Drawable[] base.Content.AddRange(new Drawable[]
{ {

View File

@ -5,6 +5,7 @@ using System;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Overlays.Dialog; using osu.Game.Overlays.Dialog;
@ -32,7 +33,7 @@ namespace osu.Game.Tests.Visual.Editing
public override void SetUpSteps() public override void SetUpSteps()
{ {
AddStep("import test beatmap", () => importedBeatmapSet = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Result); AddStep("import test beatmap", () => importedBeatmapSet = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).GetResultSafely());
base.SetUpSteps(); base.SetUpSteps();
} }

View File

@ -5,6 +5,7 @@ using System;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.Editing
public override void SetUpSteps() public override void SetUpSteps()
{ {
AddStep("import test beatmap", () => importedBeatmapSet = ImportBeatmapTest.LoadOszIntoOsu(game).Result); AddStep("import test beatmap", () => importedBeatmapSet = ImportBeatmapTest.LoadOszIntoOsu(game).GetResultSafely());
base.SetUpSteps(); base.SetUpSteps();
} }

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Screens; using osu.Framework.Screens;
@ -36,7 +37,9 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override bool HasCustomSteps => true; protected override bool HasCustomSteps => true;
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new NonImportingPlayer(false); protected override TestPlayer CreatePlayer(Ruleset ruleset) => new FakeImportingPlayer(false);
protected new FakeImportingPlayer Player => (FakeImportingPlayer)base.Player;
protected override Ruleset CreatePlayerRuleset() => createCustomRuleset?.Invoke() ?? new OsuRuleset(); protected override Ruleset CreatePlayerRuleset() => createCustomRuleset?.Invoke() ?? new OsuRuleset();
@ -54,7 +57,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test] [Test]
public void TestNoSubmissionOnResultsWithNoToken() public void TestNoSubmissionOnResultsWithNoToken()
{ {
prepareTokenResponse(false); prepareTestAPI(false);
createPlayerTest(); createPlayerTest();
@ -74,7 +77,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test] [Test]
public void TestSubmissionOnResults() public void TestSubmissionOnResults()
{ {
prepareTokenResponse(true); prepareTestAPI(true);
createPlayerTest(); createPlayerTest();
@ -93,7 +96,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test] [Test]
public void TestSubmissionForDifferentRuleset() public void TestSubmissionForDifferentRuleset()
{ {
prepareTokenResponse(true); prepareTestAPI(true);
createPlayerTest(createRuleset: () => new TaikoRuleset()); createPlayerTest(createRuleset: () => new TaikoRuleset());
@ -113,7 +116,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test] [Test]
public void TestSubmissionForConvertedBeatmap() public void TestSubmissionForConvertedBeatmap()
{ {
prepareTokenResponse(true); prepareTestAPI(true);
createPlayerTest(createRuleset: () => new ManiaRuleset(), createBeatmap: _ => createTestBeatmap(new OsuRuleset().RulesetInfo)); createPlayerTest(createRuleset: () => new ManiaRuleset(), createBeatmap: _ => createTestBeatmap(new OsuRuleset().RulesetInfo));
@ -133,7 +136,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test] [Test]
public void TestNoSubmissionOnExitWithNoToken() public void TestNoSubmissionOnExitWithNoToken()
{ {
prepareTokenResponse(false); prepareTestAPI(false);
createPlayerTest(); createPlayerTest();
@ -150,7 +153,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test] [Test]
public void TestNoSubmissionOnEmptyFail() public void TestNoSubmissionOnEmptyFail()
{ {
prepareTokenResponse(true); prepareTestAPI(true);
createPlayerTest(true); createPlayerTest(true);
@ -165,7 +168,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test] [Test]
public void TestSubmissionOnFail() public void TestSubmissionOnFail()
{ {
prepareTokenResponse(true); prepareTestAPI(true);
createPlayerTest(true); createPlayerTest(true);
@ -182,7 +185,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test] [Test]
public void TestNoSubmissionOnEmptyExit() public void TestNoSubmissionOnEmptyExit()
{ {
prepareTokenResponse(true); prepareTestAPI(true);
createPlayerTest(); createPlayerTest();
@ -195,7 +198,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test] [Test]
public void TestSubmissionOnExit() public void TestSubmissionOnExit()
{ {
prepareTokenResponse(true); prepareTestAPI(true);
createPlayerTest(); createPlayerTest();
@ -207,10 +210,29 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert("ensure failing submission", () => Player.SubmittedScore?.ScoreInfo.Passed == false); AddAssert("ensure failing submission", () => Player.SubmittedScore?.ScoreInfo.Passed == false);
} }
[Test]
public void TestSubmissionOnExitDuringImport()
{
prepareTestAPI(true);
createPlayerTest();
AddStep("block imports", () => Player.AllowImportCompletion.Wait());
AddUntilStep("wait for token request", () => Player.TokenCreationRequested);
addFakeHit();
AddUntilStep("wait for import to start", () => Player.ScoreImportStarted);
AddStep("exit", () => Player.Exit());
AddStep("allow import to proceed", () => Player.AllowImportCompletion.Release(1));
AddUntilStep("ensure submission", () => Player.SubmittedScore != null && Player.ImportedScore != null);
}
[Test] [Test]
public void TestNoSubmissionOnLocalBeatmap() public void TestNoSubmissionOnLocalBeatmap()
{ {
prepareTokenResponse(true); prepareTestAPI(true);
createPlayerTest(false, r => createPlayerTest(false, r =>
{ {
@ -231,7 +253,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[TestCase(10)] [TestCase(10)]
public void TestNoSubmissionOnCustomRuleset(int? rulesetId) public void TestNoSubmissionOnCustomRuleset(int? rulesetId)
{ {
prepareTokenResponse(true); prepareTestAPI(true);
createPlayerTest(false, createRuleset: () => new OsuRuleset { RulesetInfo = { OnlineID = rulesetId ?? -1 } }); createPlayerTest(false, createRuleset: () => new OsuRuleset { RulesetInfo = { OnlineID = rulesetId ?? -1 } });
@ -253,7 +275,7 @@ namespace osu.Game.Tests.Visual.Gameplay
})); }));
} }
private void prepareTokenResponse(bool validToken) private void prepareTestAPI(bool validToken)
{ {
AddStep("Prepare test API", () => AddStep("Prepare test API", () =>
{ {
@ -267,6 +289,31 @@ namespace osu.Game.Tests.Visual.Gameplay
else else
tokenRequest.TriggerFailure(new APIException("something went wrong!", null)); tokenRequest.TriggerFailure(new APIException("something went wrong!", null));
return true; return true;
case SubmitSoloScoreRequest submissionRequest:
if (validToken)
{
var requestScore = submissionRequest.Score;
submissionRequest.TriggerSuccess(new MultiplayerScore
{
ID = 1234,
User = dummyAPI.LocalUser.Value,
Rank = requestScore.Rank,
TotalScore = requestScore.TotalScore,
Accuracy = requestScore.Accuracy,
MaxCombo = requestScore.MaxCombo,
Mods = requestScore.Mods,
Statistics = requestScore.Statistics,
Passed = requestScore.Passed,
EndedAt = DateTimeOffset.Now,
Position = 1
});
return true;
}
break;
} }
return false; return false;
@ -288,15 +335,26 @@ namespace osu.Game.Tests.Visual.Gameplay
}); });
} }
private class NonImportingPlayer : TestPlayer protected class FakeImportingPlayer : TestPlayer
{ {
public NonImportingPlayer(bool allowPause = true, bool showResults = true, bool pauseOnFocusLost = false) public bool ScoreImportStarted { get; set; }
public SemaphoreSlim AllowImportCompletion { get; }
public Score ImportedScore { get; private set; }
public FakeImportingPlayer(bool allowPause = true, bool showResults = true, bool pauseOnFocusLost = false)
: base(allowPause, showResults, pauseOnFocusLost) : base(allowPause, showResults, pauseOnFocusLost)
{ {
AllowImportCompletion = new SemaphoreSlim(1);
} }
protected override Task ImportScore(Score score) protected override async Task ImportScore(Score score)
{ {
ScoreImportStarted = true;
await AllowImportCompletion.WaitAsync().ConfigureAwait(false);
ImportedScore = score;
// It was discovered that Score members could sometimes be half-populated. // It was discovered that Score members could sometimes be half-populated.
// In particular, the RulesetID property could be set to 0 even on non-osu! maps. // In particular, the RulesetID property could be set to 0 even on non-osu! maps.
// We want to test that the state of that property is consistent in this test. // We want to test that the state of that property is consistent in this test.
@ -311,8 +369,7 @@ namespace osu.Game.Tests.Visual.Gameplay
// In the above instance, if a ScoreInfo with Ruleset = {mania} and RulesetID = 0 is attached to an EF context, // In the above instance, if a ScoreInfo with Ruleset = {mania} and RulesetID = 0 is attached to an EF context,
// RulesetID WILL BE SILENTLY SET TO THE CORRECT VALUE of 3. // RulesetID WILL BE SILENTLY SET TO THE CORRECT VALUE of 3.
// //
// For the above reasons, importing is disabled in this test. // For the above reasons, actual importing is disabled in this test.
return Task.CompletedTask;
} }
} }
} }

View File

@ -9,6 +9,7 @@ using osu.Game.Online.API.Requests.Responses;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
@ -135,7 +136,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("state is not downloaded", () => downloadButton.State.Value == DownloadState.NotDownloaded); AddUntilStep("state is not downloaded", () => downloadButton.State.Value == DownloadState.NotDownloaded);
AddStep("import score", () => imported = scoreManager.Import(getScoreInfo(true)).Result); AddStep("import score", () => imported = scoreManager.Import(getScoreInfo(true)).GetResultSafely());
AddUntilStep("state is available", () => downloadButton.State.Value == DownloadState.LocallyAvailable); AddUntilStep("state is available", () => downloadButton.State.Value == DownloadState.LocallyAvailable);

View File

@ -4,6 +4,7 @@
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -60,7 +61,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("import beatmap", () => AddStep("import beatmap", () =>
{ {
importedBeatmap = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Result; importedBeatmap = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).GetResultSafely();
importedBeatmapId = importedBeatmap.Beatmaps.First(b => b.RulesetID == 0).OnlineID ?? -1; importedBeatmapId = importedBeatmap.Beatmaps.First(b => b.RulesetID == 0).OnlineID ?? -1;
}); });
} }

View File

@ -53,8 +53,8 @@ namespace osu.Game.Tests.Visual.Gameplay
CreateTest(null); CreateTest(null);
AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value); AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value);
AddStep("skip outro", () => InputManager.Key(osuTK.Input.Key.Space)); AddStep("skip outro", () => InputManager.Key(osuTK.Input.Key.Space));
AddAssert("player is no longer current screen", () => !Player.IsCurrentScreen());
AddUntilStep("wait for score shown", () => Player.IsScoreShown); AddUntilStep("wait for score shown", () => Player.IsScoreShown);
AddUntilStep("time less than storyboard duration", () => Player.GameplayClockContainer.GameplayClock.CurrentTime < currentStoryboardDuration);
} }
[Test] [Test]

View File

@ -4,6 +4,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Database; using osu.Game.Database;
@ -33,11 +34,11 @@ namespace osu.Game.Tests.Visual.Menus
Queue<(IWorkingBeatmap working, TrackChangeDirection changeDirection)> trackChangeQueue = null; Queue<(IWorkingBeatmap working, TrackChangeDirection changeDirection)> trackChangeQueue = null;
// ensure we have at least two beatmaps available to identify the direction the music controller navigated to. // ensure we have at least two beatmaps available to identify the direction the music controller navigated to.
AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(TestResources.CreateTestBeatmapSetInfo()).Wait(), 5); AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(TestResources.CreateTestBeatmapSetInfo()).WaitSafely(), 5);
AddStep("import beatmap with track", () => AddStep("import beatmap with track", () =>
{ {
var setWithTrack = Game.BeatmapManager.Import(new ImportTask(TestResources.GetTestBeatmapForImport())).Result; var setWithTrack = Game.BeatmapManager.Import(new ImportTask(TestResources.GetTestBeatmapForImport())).GetResultSafely();
Beatmap.Value = Game.BeatmapManager.GetWorkingBeatmap(setWithTrack.Value.Beatmaps.First()); Beatmap.Value = Game.BeatmapManager.GetWorkingBeatmap(setWithTrack.Value.Beatmaps.First());
}); });

View File

@ -5,6 +5,7 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -56,7 +57,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("import beatmap", () => AddStep("import beatmap", () =>
{ {
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First(); importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
InitialBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0); InitialBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
OtherBeatmap = importedSet.Beatmaps.Last(b => b.RulesetID == 0); OtherBeatmap = importedSet.Beatmaps.Last(b => b.RulesetID == 0);

View File

@ -1,13 +1,25 @@
// 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.
#nullable enable
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.OnlinePlay.Multiplayer; using osu.Game.Screens.OnlinePlay.Multiplayer;
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
using osu.Game.Screens.Play;
using osuTK.Input; using osuTK.Input;
namespace osu.Game.Tests.Visual.Multiplayer namespace osu.Game.Tests.Visual.Multiplayer
@ -83,16 +95,60 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID); AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
} }
private void addItem(Func<BeatmapInfo> beatmap) [Test]
public void TestCorrectRulesetSelectedAfterNewItemAdded()
{ {
addItem(() => OtherBeatmap, new CatchRuleset().RulesetInfo);
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
AddUntilStep("wait for idle", () => Client.LocalUser?.State == MultiplayerUserState.Idle);
ClickButtonWhenEnabled<MultiplayerReadyButton>();
AddUntilStep("wait for ready", () => Client.LocalUser?.State == MultiplayerUserState.Ready);
ClickButtonWhenEnabled<MultiplayerReadyButton>();
AddUntilStep("wait for player", () => CurrentScreen is Player player && player.IsLoaded);
AddAssert("ruleset is correct", () => ((Player)CurrentScreen).Ruleset.Value.Equals(new OsuRuleset().RulesetInfo));
AddStep("exit player", () => CurrentScreen.Exit());
}
[Test]
public void TestCorrectModsSelectedAfterNewItemAdded()
{
addItem(() => OtherBeatmap, mods: new Mod[] { new OsuModDoubleTime() });
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
AddUntilStep("wait for idle", () => Client.LocalUser?.State == MultiplayerUserState.Idle);
ClickButtonWhenEnabled<MultiplayerReadyButton>();
AddUntilStep("wait for ready", () => Client.LocalUser?.State == MultiplayerUserState.Ready);
ClickButtonWhenEnabled<MultiplayerReadyButton>();
AddUntilStep("wait for player", () => CurrentScreen is Player player && player.IsLoaded);
AddAssert("mods are correct", () => !((Player)CurrentScreen).Mods.Value.Any());
AddStep("exit player", () => CurrentScreen.Exit());
}
private void addItem(Func<BeatmapInfo> beatmap, RulesetInfo? ruleset = null, IReadOnlyList<Mod>? mods = null)
{
Screens.Select.SongSelect? songSelect = null;
AddStep("click add button", () => AddStep("click add button", () =>
{ {
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen.AddItemButton>().Single()); InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen.AddItemButton>().Single());
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded); AddUntilStep("wait for song select", () => (songSelect = CurrentSubScreen as Screens.Select.SongSelect) != null);
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(beatmap())); AddUntilStep("wait for loaded", () => songSelect.AsNonNull().BeatmapSetsLoaded);
if (ruleset != null)
AddStep($"set {ruleset.Name} ruleset", () => songSelect.AsNonNull().Ruleset.Value = ruleset);
if (mods != null)
AddStep($"set mods to {string.Join(",", mods.Select(m => m.Acronym))}", () => songSelect.AsNonNull().Mods.Value = mods);
AddStep("select other beatmap", () => songSelect.AsNonNull().FinaliseSelection(beatmap()));
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen); AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
} }
} }

View File

@ -8,6 +8,7 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Platform; using osu.Framework.Platform;
@ -153,7 +154,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
var beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo; var beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo;
AddStep("import beatmap", () => manager.Import(beatmap.BeatmapSet).Wait()); AddStep("import beatmap", () => manager.Import(beatmap.BeatmapSet).WaitSafely());
createPlaylistWithBeatmaps(beatmap); createPlaylistWithBeatmaps(beatmap);

View File

@ -50,6 +50,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
}); });
AddUntilStep("wait for load", () => leaderboard.IsLoaded); AddUntilStep("wait for load", () => leaderboard.IsLoaded);
AddUntilStep("wait for user population", () => leaderboard.ChildrenOfType<GameplayLeaderboardScore>().Count() == 2);
AddStep("add clock sources", () => AddStep("add clock sources", () =>
{ {

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -46,7 +47,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
importedSet = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Result; importedSet = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).GetResultSafely();
importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0); importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
importedBeatmapId = importedBeatmap.OnlineID ?? -1; importedBeatmapId = importedBeatmap.OnlineID ?? -1;
} }

View File

@ -7,6 +7,8 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input; using osu.Framework.Input;
@ -22,6 +24,8 @@ using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.OnlinePlay.Components; using osu.Game.Screens.OnlinePlay.Components;
@ -67,7 +71,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("import beatmap", () => AddStep("import beatmap", () =>
{ {
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First(); importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
}); });
@ -438,6 +442,84 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddAssert("Beatmap matches current item", () => Beatmap.Value.BeatmapInfo.OnlineID == client.Room?.Playlist.First().BeatmapID); AddAssert("Beatmap matches current item", () => Beatmap.Value.BeatmapInfo.OnlineID == client.Room?.Playlist.First().BeatmapID);
} }
[Test]
public void TestPlayStartsWithCorrectRulesetWhileAtSongSelect()
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Playlist =
{
new PlaylistItem
{
Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo },
Ruleset = { Value = new OsuRuleset().RulesetInfo },
}
}
});
pressReadyButton();
AddStep("Enter song select", () =>
{
var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerComponents.CurrentScreen).CurrentSubScreen;
((MultiplayerMatchSubScreen)currentSubScreen).OpenSongSelection(client.Room?.Settings.PlaylistItemId);
});
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
AddAssert("Ruleset matches current item", () => Ruleset.Value.OnlineID == client.Room?.Playlist.First().RulesetID);
AddStep("Switch ruleset", () => ((MultiplayerMatchSongSelect)multiplayerComponents.MultiplayerScreen.CurrentSubScreen).Ruleset.Value = new CatchRuleset().RulesetInfo);
AddUntilStep("Ruleset doesn't match current item", () => Ruleset.Value.OnlineID != client.Room?.Playlist.First().RulesetID);
AddStep("start match externally", () => client.StartMatch());
AddUntilStep("play started", () => multiplayerComponents.CurrentScreen is Player);
AddAssert("Ruleset matches current item", () => Ruleset.Value.OnlineID == client.Room?.Playlist.First().RulesetID);
}
[Test]
public void TestPlayStartsWithCorrectModsWhileAtSongSelect()
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Playlist =
{
new PlaylistItem
{
Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo },
Ruleset = { Value = new OsuRuleset().RulesetInfo },
}
}
});
pressReadyButton();
AddStep("Enter song select", () =>
{
var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerComponents.CurrentScreen).CurrentSubScreen;
((MultiplayerMatchSubScreen)currentSubScreen).OpenSongSelection(client.Room?.Settings.PlaylistItemId);
});
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
AddAssert("Mods match current item", () => SelectedMods.Value.Select(m => m.Acronym).SequenceEqual(client.Room.AsNonNull().Playlist.First().RequiredMods.Select(m => m.Acronym)));
AddStep("Switch required mods", () => ((MultiplayerMatchSongSelect)multiplayerComponents.MultiplayerScreen.CurrentSubScreen).Mods.Value = new Mod[] { new OsuModDoubleTime() });
AddAssert("Mods don't match current item", () => !SelectedMods.Value.Select(m => m.Acronym).SequenceEqual(client.Room.AsNonNull().Playlist.First().RequiredMods.Select(m => m.Acronym)));
AddStep("start match externally", () => client.StartMatch());
AddUntilStep("play started", () => multiplayerComponents.CurrentScreen is Player);
AddAssert("Mods match current item", () => SelectedMods.Value.Select(m => m.Acronym).SequenceEqual(client.Room.AsNonNull().Playlist.First().RequiredMods.Select(m => m.Acronym)));
}
[Test] [Test]
public void TestLocalPlayDoesNotStartWhileSpectatingWithNoBeatmap() public void TestLocalPlayDoesNotStartWhileSpectatingWithNoBeatmap()
{ {
@ -505,7 +587,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("restore beatmap", () => AddStep("restore beatmap", () =>
{ {
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First(); importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
}); });

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Utils; using osu.Framework.Utils;
@ -43,7 +44,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
base.SetUpSteps(); base.SetUpSteps();
AddStep("set local user", () => ((DummyAPIAccess)API).LocalUser.Value = LookupCache.GetUserAsync(1).Result); AddStep("set local user", () => ((DummyAPIAccess)API).LocalUser.Value = LookupCache.GetUserAsync(1).GetResultSafely());
AddStep("create leaderboard", () => AddStep("create leaderboard", () =>
{ {
@ -90,7 +91,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public void TestUserQuit() public void TestUserQuit()
{ {
foreach (int user in users) foreach (int user in users)
AddStep($"mark user {user} quit", () => Client.RemoveUser(LookupCache.GetUserAsync(user).Result.AsNonNull())); AddStep($"mark user {user} quit", () => Client.RemoveUser(LookupCache.GetUserAsync(user).GetResultSafely().AsNonNull()));
} }
[Test] [Test]

View File

@ -4,6 +4,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Online.API; using osu.Game.Online.API;
@ -47,7 +48,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
base.SetUpSteps(); base.SetUpSteps();
AddStep("set local user", () => ((DummyAPIAccess)API).LocalUser.Value = LookupCache.GetUserAsync(1).Result); AddStep("set local user", () => ((DummyAPIAccess)API).LocalUser.Value = LookupCache.GetUserAsync(1).GetResultSafely());
AddStep("create leaderboard", () => AddStep("create leaderboard", () =>
{ {

View File

@ -83,7 +83,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
beatmapSetInfo.Beatmaps.Add(beatmap); beatmapSetInfo.Beatmaps.Add(beatmap);
} }
manager.Import(beatmapSetInfo).Wait(); manager.Import(beatmapSetInfo).WaitSafely();
} }
public override void SetUpSteps() public override void SetUpSteps()

View File

@ -5,6 +5,7 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -39,7 +40,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory)); Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First(); importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
} }

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -53,7 +54,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
AddStep("import beatmap", () => AddStep("import beatmap", () =>
{ {
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First(); importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0); importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
}); });

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Platform; using osu.Framework.Platform;
@ -58,7 +59,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("import beatmap", () => AddStep("import beatmap", () =>
{ {
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First(); importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0); importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
}); });

View File

@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -41,7 +42,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory)); Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
} }
[SetUp] [SetUp]

View File

@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Platform; using osu.Framework.Platform;
@ -42,7 +43,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory)); Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
} }
[SetUp] [SetUp]

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Utils; using osu.Framework.Utils;
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
var beatmapSet = TestResources.CreateTestBeatmapSetInfo(); var beatmapSet = TestResources.CreateTestBeatmapSetInfo();
manager.Import(beatmapSet).Wait(); manager.Import(beatmapSet).WaitSafely();
} }
public override void SetUpSteps() public override void SetUpSteps()

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -51,7 +52,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("import beatmap", () => AddStep("import beatmap", () =>
{ {
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First(); importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
}); });

View File

@ -2,6 +2,7 @@
// 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 NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps.IO; using osu.Game.Tests.Beatmaps.IO;
@ -82,7 +83,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => songSelect = new TestSceneScreenNavigation.TestPlaySongSelect()); PushAndConfirm(() => songSelect = new TestSceneScreenNavigation.TestPlaySongSelect());
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded); AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait()); AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).WaitSafely());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault); AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
AddStep("press enter", () => InputManager.Key(Key.Enter)); AddStep("press enter", () => InputManager.Key(Key.Enter));

View File

@ -4,6 +4,7 @@
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -172,7 +173,7 @@ namespace osu.Game.Tests.Visual.Navigation
private void importAndWaitForSongSelect() private void importAndWaitForSongSelect()
{ {
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait()); AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).WaitSafely());
PushAndConfirm(() => new TestPlaySongSelect()); PushAndConfirm(() => new TestPlaySongSelect());
AddUntilStep("beatmap updated", () => Game.Beatmap.Value.BeatmapSetInfo.OnlineID == 241526); AddUntilStep("beatmap updated", () => Game.Beatmap.Value.BeatmapSetInfo.OnlineID == 241526);
} }

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Extensions; using osu.Game.Extensions;
@ -20,30 +21,30 @@ namespace osu.Game.Tests.Visual.Navigation
public void TestFromMainMenu() public void TestFromMainMenu()
{ {
var firstImport = importBeatmap(1); var firstImport = importBeatmap(1);
var secondimport = importBeatmap(3); var secondImport = importBeatmap(3);
presentAndConfirm(firstImport); presentAndConfirm(firstImport);
returnToMenu(); returnToMenu();
presentAndConfirm(secondimport); presentAndConfirm(secondImport);
returnToMenu(); returnToMenu();
presentSecondDifficultyAndConfirm(firstImport, 1); presentSecondDifficultyAndConfirm(firstImport, 1);
returnToMenu(); returnToMenu();
presentSecondDifficultyAndConfirm(secondimport, 3); presentSecondDifficultyAndConfirm(secondImport, 3);
} }
[Test] [Test]
public void TestFromMainMenuDifferentRuleset() public void TestFromMainMenuDifferentRuleset()
{ {
var firstImport = importBeatmap(1); var firstImport = importBeatmap(1);
var secondimport = importBeatmap(3, new ManiaRuleset().RulesetInfo); var secondImport = importBeatmap(3, new ManiaRuleset().RulesetInfo);
presentAndConfirm(firstImport); presentAndConfirm(firstImport);
returnToMenu(); returnToMenu();
presentAndConfirm(secondimport); presentAndConfirm(secondImport);
returnToMenu(); returnToMenu();
presentSecondDifficultyAndConfirm(firstImport, 1); presentSecondDifficultyAndConfirm(firstImport, 1);
returnToMenu(); returnToMenu();
presentSecondDifficultyAndConfirm(secondimport, 3); presentSecondDifficultyAndConfirm(secondImport, 3);
} }
[Test] [Test]
@ -52,17 +53,17 @@ namespace osu.Game.Tests.Visual.Navigation
var firstImport = importBeatmap(1); var firstImport = importBeatmap(1);
presentAndConfirm(firstImport); presentAndConfirm(firstImport);
var secondimport = importBeatmap(3); var secondImport = importBeatmap(3);
presentAndConfirm(secondimport); presentAndConfirm(secondImport);
// Test presenting same beatmap more than once // Test presenting same beatmap more than once
presentAndConfirm(secondimport); presentAndConfirm(secondImport);
presentSecondDifficultyAndConfirm(firstImport, 1); presentSecondDifficultyAndConfirm(firstImport, 1);
presentSecondDifficultyAndConfirm(secondimport, 3); presentSecondDifficultyAndConfirm(secondImport, 3);
// Test presenting same beatmap more than once // Test presenting same beatmap more than once
presentSecondDifficultyAndConfirm(secondimport, 3); presentSecondDifficultyAndConfirm(secondImport, 3);
} }
[Test] [Test]
@ -71,11 +72,11 @@ namespace osu.Game.Tests.Visual.Navigation
var firstImport = importBeatmap(1); var firstImport = importBeatmap(1);
presentAndConfirm(firstImport); presentAndConfirm(firstImport);
var secondimport = importBeatmap(3, new ManiaRuleset().RulesetInfo); var secondImport = importBeatmap(3, new ManiaRuleset().RulesetInfo);
presentAndConfirm(secondimport); presentAndConfirm(secondImport);
presentSecondDifficultyAndConfirm(firstImport, 1); presentSecondDifficultyAndConfirm(firstImport, 1);
presentSecondDifficultyAndConfirm(secondimport, 3); presentSecondDifficultyAndConfirm(secondImport, 3);
} }
private void returnToMenu() private void returnToMenu()
@ -126,7 +127,7 @@ namespace osu.Game.Tests.Visual.Navigation
Ruleset = ruleset ?? new OsuRuleset().RulesetInfo Ruleset = ruleset ?? new OsuRuleset().RulesetInfo
}, },
} }
}).Result.Value; }).GetResultSafely().Value;
}); });
AddAssert($"import {i} succeeded", () => imported != null); AddAssert($"import {i} succeeded", () => imported != null);

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -57,7 +58,7 @@ namespace osu.Game.Tests.Visual.Navigation
Ruleset = new OsuRuleset().RulesetInfo Ruleset = new OsuRuleset().RulesetInfo
}, },
} }
}).Result.Value; }).GetResultSafely().Value;
}); });
} }
@ -65,11 +66,11 @@ namespace osu.Game.Tests.Visual.Navigation
public void TestFromMainMenu([Values] ScorePresentType type) public void TestFromMainMenu([Values] ScorePresentType type)
{ {
var firstImport = importScore(1); var firstImport = importScore(1);
var secondimport = importScore(3); var secondImport = importScore(3);
presentAndConfirm(firstImport, type); presentAndConfirm(firstImport, type);
returnToMenu(); returnToMenu();
presentAndConfirm(secondimport, type); presentAndConfirm(secondImport, type);
returnToMenu(); returnToMenu();
returnToMenu(); returnToMenu();
} }
@ -78,11 +79,11 @@ namespace osu.Game.Tests.Visual.Navigation
public void TestFromMainMenuDifferentRuleset([Values] ScorePresentType type) public void TestFromMainMenuDifferentRuleset([Values] ScorePresentType type)
{ {
var firstImport = importScore(1); var firstImport = importScore(1);
var secondimport = importScore(3, new ManiaRuleset().RulesetInfo); var secondImport = importScore(3, new ManiaRuleset().RulesetInfo);
presentAndConfirm(firstImport, type); presentAndConfirm(firstImport, type);
returnToMenu(); returnToMenu();
presentAndConfirm(secondimport, type); presentAndConfirm(secondImport, type);
returnToMenu(); returnToMenu();
returnToMenu(); returnToMenu();
} }
@ -93,8 +94,8 @@ namespace osu.Game.Tests.Visual.Navigation
var firstImport = importScore(1); var firstImport = importScore(1);
presentAndConfirm(firstImport, type); presentAndConfirm(firstImport, type);
var secondimport = importScore(3); var secondImport = importScore(3);
presentAndConfirm(secondimport, type); presentAndConfirm(secondImport, type);
} }
[Test] [Test]
@ -103,8 +104,8 @@ namespace osu.Game.Tests.Visual.Navigation
var firstImport = importScore(1); var firstImport = importScore(1);
presentAndConfirm(firstImport, type); presentAndConfirm(firstImport, type);
var secondimport = importScore(3, new ManiaRuleset().RulesetInfo); var secondImport = importScore(3, new ManiaRuleset().RulesetInfo);
presentAndConfirm(secondimport, type); presentAndConfirm(secondImport, type);
} }
private void returnToMenu() private void returnToMenu()
@ -131,7 +132,7 @@ namespace osu.Game.Tests.Visual.Navigation
OnlineID = i, OnlineID = i,
BeatmapInfo = beatmap.Beatmaps.First(), BeatmapInfo = beatmap.Beatmaps.First(),
Ruleset = ruleset ?? new OsuRuleset().RulesetInfo Ruleset = ruleset ?? new OsuRuleset().RulesetInfo
}).Result.Value; }).GetResultSafely().Value;
}); });
AddAssert($"import {i} succeeded", () => imported != null); AddAssert($"import {i} succeeded", () => imported != null);

View File

@ -4,6 +4,7 @@
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -70,7 +71,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => songSelect = new TestPlaySongSelect()); PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded); AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait()); AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).WaitSafely());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault); AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
@ -104,7 +105,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => songSelect = new TestPlaySongSelect()); PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded); AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait()); AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).WaitSafely());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault); AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
@ -138,7 +139,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => songSelect = new TestPlaySongSelect()); PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded); AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait()); AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).WaitSafely());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault); AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);

View File

@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual.Online
}, },
}); });
visiblityAssert(true); visibilityAssert(true);
} }
[Test] [Test]
@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual.Online
}, },
}); });
visiblityAssert(true); visibilityAssert(true);
} }
[Test] [Test]
@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.Online
}, },
}); });
visiblityAssert(true); visibilityAssert(true);
} }
[Test] [Test]
@ -73,10 +73,10 @@ namespace osu.Game.Tests.Visual.Online
}, },
}); });
visiblityAssert(false); visibilityAssert(false);
} }
private void visiblityAssert(bool shown) private void visibilityAssert(bool shown)
{ {
AddAssert($"is container {(shown ? "visible" : "hidden")}", () => container.Alpha == (shown ? 1 : 0)); AddAssert($"is container {(shown ? "visible" : "hidden")}", () => container.Alpha == (shown ? 1 : 0));
} }

View File

@ -107,19 +107,31 @@ namespace osu.Game.Tests.Visual.Online
AddUntilStep("is hidden", () => overlay.State.Value == Visibility.Hidden); AddUntilStep("is hidden", () => overlay.State.Value == Visibility.Hidden);
} }
[Test]
public void TestCorrectOldContentExpiration()
{
AddAssert("is visible", () => overlay.State.Value == Visibility.Visible);
AddStep("show many results", () => fetchFor(Enumerable.Repeat(CreateAPIBeatmapSet(Ruleset.Value), 100).ToArray()));
assertAllCardsOfType<BeatmapCardNormal>(100);
AddStep("show more results", () => fetchFor(Enumerable.Repeat(CreateAPIBeatmapSet(Ruleset.Value), 30).ToArray()));
assertAllCardsOfType<BeatmapCardNormal>(30);
}
[Test] [Test]
public void TestCardSizeSwitching() public void TestCardSizeSwitching()
{ {
AddAssert("is visible", () => overlay.State.Value == Visibility.Visible); AddAssert("is visible", () => overlay.State.Value == Visibility.Visible);
AddStep("show many results", () => fetchFor(Enumerable.Repeat(CreateAPIBeatmapSet(Ruleset.Value), 100).ToArray())); AddStep("show many results", () => fetchFor(Enumerable.Repeat(CreateAPIBeatmapSet(Ruleset.Value), 100).ToArray()));
assertAllCardsOfType<BeatmapCardNormal>(); assertAllCardsOfType<BeatmapCardNormal>(100);
setCardSize(BeatmapCardSize.Extra); setCardSize(BeatmapCardSize.Extra);
assertAllCardsOfType<BeatmapCardExtra>(); assertAllCardsOfType<BeatmapCardExtra>(100);
setCardSize(BeatmapCardSize.Normal); setCardSize(BeatmapCardSize.Normal);
assertAllCardsOfType<BeatmapCardNormal>(); assertAllCardsOfType<BeatmapCardNormal>(100);
AddStep("fetch for 0 beatmaps", () => fetchFor()); AddStep("fetch for 0 beatmaps", () => fetchFor());
AddUntilStep("placeholder shown", () => overlay.ChildrenOfType<BeatmapListingOverlay.NotFoundDrawable>().SingleOrDefault()?.IsPresent == true); AddUntilStep("placeholder shown", () => overlay.ChildrenOfType<BeatmapListingOverlay.NotFoundDrawable>().SingleOrDefault()?.IsPresent == true);
@ -323,13 +335,12 @@ namespace osu.Game.Tests.Visual.Online
private void setCardSize(BeatmapCardSize cardSize) => AddStep($"set card size to {cardSize}", () => overlay.ChildrenOfType<BeatmapListingCardSizeTabControl>().Single().Current.Value = cardSize); private void setCardSize(BeatmapCardSize cardSize) => AddStep($"set card size to {cardSize}", () => overlay.ChildrenOfType<BeatmapListingCardSizeTabControl>().Single().Current.Value = cardSize);
private void assertAllCardsOfType<T>() private void assertAllCardsOfType<T>(int expectedCount)
where T : BeatmapCard => where T : BeatmapCard =>
AddUntilStep($"all loaded beatmap cards are {typeof(T)}", () => AddUntilStep($"all loaded beatmap cards are {typeof(T)}", () =>
{ {
int loadedCorrectCount = this.ChildrenOfType<BeatmapCard>().Count(card => card.IsLoaded && card.GetType() == typeof(T)); int loadedCorrectCount = this.ChildrenOfType<BeatmapCard>().Count(card => card.IsLoaded && card.GetType() == typeof(T));
int totalCount = this.ChildrenOfType<BeatmapCard>().Count(); return loadedCorrectCount > 0 && loadedCorrectCount == expectedCount;
return loadedCorrectCount > 0 && loadedCorrectCount == totalCount;
}); });
} }
} }

View File

@ -50,18 +50,58 @@ namespace osu.Game.Tests.Visual.Online
Dependencies.Cache(new ChatOverlay()); Dependencies.Cache(new ChatOverlay());
Dependencies.Cache(dialogOverlay); Dependencies.Cache(dialogOverlay);
testLinksGeneral();
testEcho();
} }
private void clear() => AddStep("clear messages", textContainer.Clear); [SetUp]
public void Setup() => Schedule(() =>
private void addMessageWithChecks(string text, int linkAmount = 0, bool isAction = false, bool isImportant = false, params LinkAction[] expectedActions)
{ {
int index = textContainer.Count + 1; textContainer.Clear();
var newLine = new ChatLine(new DummyMessage(text, isAction, isImportant, index)); });
[Test]
public void TestLinksGeneral()
{
int messageIndex = 0;
addMessageWithChecks("test!");
addMessageWithChecks("dev.ppy.sh!");
addMessageWithChecks("https://dev.ppy.sh!", 1, expectedActions: LinkAction.External);
addMessageWithChecks("00:12:345 (1,2) - Test?", 1, expectedActions: LinkAction.OpenEditorTimestamp);
addMessageWithChecks("Wiki link for tasty [[Performance Points]]", 1, expectedActions: LinkAction.OpenWiki);
addMessageWithChecks("(osu forums)[https://dev.ppy.sh/forum] (old link format)", 1, expectedActions: LinkAction.External);
addMessageWithChecks("[https://dev.ppy.sh/home New site] (new link format)", 1, expectedActions: LinkAction.External);
addMessageWithChecks("[osu forums](https://dev.ppy.sh/forum) (new link format 2)", 1, expectedActions: LinkAction.External);
addMessageWithChecks("[https://dev.ppy.sh/home This is only a link to the new osu webpage but this is supposed to test word wrap.]", 1, expectedActions: LinkAction.External);
addMessageWithChecks("is now listening to [https://dev.ppy.sh/s/93523 IMAGE -MATERIAL- <Version 0>]", 1, true, expectedActions: LinkAction.OpenBeatmapSet);
addMessageWithChecks("is now playing [https://dev.ppy.sh/b/252238 IMAGE -MATERIAL- <Version 0>]", 1, true, expectedActions: LinkAction.OpenBeatmap);
addMessageWithChecks("Let's (try)[https://dev.ppy.sh/home] [https://dev.ppy.sh/b/252238 multiple links] https://dev.ppy.sh/home", 3,
expectedActions: new[] { LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External });
addMessageWithChecks("[https://dev.ppy.sh/home New link format with escaped [and \\[ paired] braces]", 1, expectedActions: LinkAction.External);
addMessageWithChecks("[Markdown link format with escaped [and \\[ paired] braces](https://dev.ppy.sh/home)", 1, expectedActions: LinkAction.External);
addMessageWithChecks("(Old link format with escaped (and \\( paired) parentheses)[https://dev.ppy.sh/home] and [[also a rogue wiki link]]", 2,
expectedActions: new[] { LinkAction.External, LinkAction.OpenWiki });
// note that there's 0 links here (they get removed if a channel is not found)
addMessageWithChecks("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present).");
addMessageWithChecks("I am important!", 0, false, true);
addMessageWithChecks("feels important", 0, true, true);
addMessageWithChecks("likes to post this [https://dev.ppy.sh/home link].", 1, true, true, expectedActions: LinkAction.External);
addMessageWithChecks("Join my multiplayer game osump://12346.", 1, expectedActions: LinkAction.JoinMultiplayerMatch);
addMessageWithChecks("Join my [multiplayer game](osump://12346).", 1, expectedActions: LinkAction.JoinMultiplayerMatch);
addMessageWithChecks("Join my [#english](osu://chan/#english).", 1, expectedActions: LinkAction.OpenChannel);
addMessageWithChecks("Join my osu://chan/#english.", 1, expectedActions: LinkAction.OpenChannel);
addMessageWithChecks("Join my #english or #japanese channels.", 2, expectedActions: new[] { LinkAction.OpenChannel, LinkAction.OpenChannel });
addMessageWithChecks("Join my #english or #nonexistent #hashtag channels.", 1, expectedActions: LinkAction.OpenChannel);
void addMessageWithChecks(string text, int linkAmount = 0, bool isAction = false, bool isImportant = false, params LinkAction[] expectedActions)
{
ChatLine newLine = null;
int index = messageIndex++;
AddStep("add message", () =>
{
newLine = new ChatLine(new DummyMessage(text, isAction, isImportant, index));
textContainer.Add(newLine); textContainer.Add(newLine);
});
AddAssert($"msg #{index} has {linkAmount} link(s)", () => newLine.Message.Links.Count == linkAmount); AddAssert($"msg #{index} has {linkAmount} link(s)", () => newLine.Message.Links.Count == linkAmount);
AddAssert($"msg #{index} has the right action", hasExpectedActions); AddAssert($"msg #{index} has the right action", hasExpectedActions);
@ -99,41 +139,12 @@ namespace osu.Game.Tests.Visual.Online
&& newLine.ContentFlow.Except(linkSprites.Concat(linkCompilers)).All(d => d.Colour == textColour); && newLine.ContentFlow.Except(linkSprites.Concat(linkCompilers)).All(d => d.Colour == textColour);
} }
} }
private void testLinksGeneral()
{
addMessageWithChecks("test!");
addMessageWithChecks("dev.ppy.sh!");
addMessageWithChecks("https://dev.ppy.sh!", 1, expectedActions: LinkAction.External);
addMessageWithChecks("00:12:345 (1,2) - Test?", 1, expectedActions: LinkAction.OpenEditorTimestamp);
addMessageWithChecks("Wiki link for tasty [[Performance Points]]", 1, expectedActions: LinkAction.External);
addMessageWithChecks("(osu forums)[https://dev.ppy.sh/forum] (old link format)", 1, expectedActions: LinkAction.External);
addMessageWithChecks("[https://dev.ppy.sh/home New site] (new link format)", 1, expectedActions: LinkAction.External);
addMessageWithChecks("[osu forums](https://dev.ppy.sh/forum) (new link format 2)", 1, expectedActions: LinkAction.External);
addMessageWithChecks("[https://dev.ppy.sh/home This is only a link to the new osu webpage but this is supposed to test word wrap.]", 1, expectedActions: LinkAction.External);
addMessageWithChecks("is now listening to [https://dev.ppy.sh/s/93523 IMAGE -MATERIAL- <Version 0>]", 1, true, expectedActions: LinkAction.OpenBeatmapSet);
addMessageWithChecks("is now playing [https://dev.ppy.sh/b/252238 IMAGE -MATERIAL- <Version 0>]", 1, true, expectedActions: LinkAction.OpenBeatmap);
addMessageWithChecks("Let's (try)[https://dev.ppy.sh/home] [https://dev.ppy.sh/b/252238 multiple links] https://dev.ppy.sh/home", 3,
expectedActions: new[] { LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External });
addMessageWithChecks("[https://dev.ppy.sh/home New link format with escaped [and \\[ paired] braces]", 1, expectedActions: LinkAction.External);
addMessageWithChecks("[Markdown link format with escaped [and \\[ paired] braces](https://dev.ppy.sh/home)", 1, expectedActions: LinkAction.External);
addMessageWithChecks("(Old link format with escaped (and \\( paired) parentheses)[https://dev.ppy.sh/home] and [[also a rogue wiki link]]", 2, expectedActions: new[] { LinkAction.External, LinkAction.External });
// note that there's 0 links here (they get removed if a channel is not found)
addMessageWithChecks("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present).");
addMessageWithChecks("I am important!", 0, false, true);
addMessageWithChecks("feels important", 0, true, true);
addMessageWithChecks("likes to post this [https://dev.ppy.sh/home link].", 1, true, true, expectedActions: LinkAction.External);
addMessageWithChecks("Join my multiplayer game osump://12346.", 1, expectedActions: LinkAction.JoinMultiplayerMatch);
addMessageWithChecks("Join my [multiplayer game](osump://12346).", 1, expectedActions: LinkAction.JoinMultiplayerMatch);
addMessageWithChecks("Join my [#english](osu://chan/#english).", 1, expectedActions: LinkAction.OpenChannel);
addMessageWithChecks("Join my osu://chan/#english.", 1, expectedActions: LinkAction.OpenChannel);
addMessageWithChecks("Join my #english or #japanese channels.", 2, expectedActions: new[] { LinkAction.OpenChannel, LinkAction.OpenChannel });
addMessageWithChecks("Join my #english or #nonexistent #hashtag channels.", 1, expectedActions: LinkAction.OpenChannel);
} }
private void testEcho() [Test]
public void TestEcho()
{ {
int echoCounter = 0; int messageIndex = 0;
addEchoWithWait("sent!", "received!"); addEchoWithWait("sent!", "received!");
addEchoWithWait("https://dev.ppy.sh/home", null, 500); addEchoWithWait("https://dev.ppy.sh/home", null, 500);
@ -142,15 +153,16 @@ namespace osu.Game.Tests.Visual.Online
void addEchoWithWait(string text, string completeText = null, double delay = 250) void addEchoWithWait(string text, string completeText = null, double delay = 250)
{ {
var newLine = new ChatLine(new DummyEchoMessage(text)); int index = messageIndex++;
AddStep($"send msg #{++echoCounter} after {delay}ms", () => AddStep($"send msg #{index} after {delay}ms", () =>
{ {
ChatLine newLine = new ChatLine(new DummyEchoMessage(text));
textContainer.Add(newLine); textContainer.Add(newLine);
Scheduler.AddDelayed(() => newLine.Message = new DummyMessage(completeText ?? text), delay); Scheduler.AddDelayed(() => newLine.Message = new DummyMessage(completeText ?? text), delay);
}); });
AddUntilStep($"wait for msg #{echoCounter}", () => textContainer.All(line => line.Message is DummyMessage)); AddUntilStep($"wait for msg #{index}", () => textContainer.All(line => line.Message is DummyMessage));
} }
} }

View File

@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual.Online
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
background.Colour = colours.GreySeafoam; background.Colour = colours.GreySeaFoam;
} }
private readonly IEnumerable<APIKudosuHistory> items = new[] private readonly IEnumerable<APIKudosuHistory> items = new[]

View File

@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.Online
{ {
AddStep("Load user", () => user.Value = user_with_filled_values); AddStep("Load user", () => user.Value = user_with_filled_values);
AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Section is visible", () => section.Alpha == 1);
AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlaycounts.Length == getChartValuesLength()); AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength());
} }
[Test] [Test]
@ -108,13 +108,13 @@ namespace osu.Game.Tests.Visual.Online
private static readonly APIUser user_with_empty_values = new APIUser private static readonly APIUser user_with_empty_values = new APIUser
{ {
Id = 2, Id = 2,
MonthlyPlaycounts = Array.Empty<APIUserHistoryCount>() MonthlyPlayCounts = Array.Empty<APIUserHistoryCount>()
}; };
private static readonly APIUser user_with_one_value = new APIUser private static readonly APIUser user_with_one_value = new APIUser
{ {
Id = 3, Id = 3,
MonthlyPlaycounts = new[] MonthlyPlayCounts = new[]
{ {
new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 100 } new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 100 }
} }
@ -123,7 +123,7 @@ namespace osu.Game.Tests.Visual.Online
private static readonly APIUser user_with_two_values = new APIUser private static readonly APIUser user_with_two_values = new APIUser
{ {
Id = 4, Id = 4,
MonthlyPlaycounts = new[] MonthlyPlayCounts = new[]
{ {
new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 1 }, new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 1 },
new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 2 } new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 2 }
@ -133,7 +133,7 @@ namespace osu.Game.Tests.Visual.Online
private static readonly APIUser user_with_constant_values = new APIUser private static readonly APIUser user_with_constant_values = new APIUser
{ {
Id = 5, Id = 5,
MonthlyPlaycounts = new[] MonthlyPlayCounts = new[]
{ {
new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 5 }, new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 5 },
new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 5 }, new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 5 },
@ -144,7 +144,7 @@ namespace osu.Game.Tests.Visual.Online
private static readonly APIUser user_with_zero_values = new APIUser private static readonly APIUser user_with_zero_values = new APIUser
{ {
Id = 6, Id = 6,
MonthlyPlaycounts = new[] MonthlyPlayCounts = new[]
{ {
new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 0 }, new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 0 },
new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 0 }, new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 0 },
@ -155,7 +155,7 @@ namespace osu.Game.Tests.Visual.Online
private static readonly APIUser user_with_filled_values = new APIUser private static readonly APIUser user_with_filled_values = new APIUser
{ {
Id = 7, Id = 7,
MonthlyPlaycounts = new[] MonthlyPlayCounts = new[]
{ {
new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 1000 }, new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 1000 },
new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 20 }, new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 20 },
@ -170,7 +170,7 @@ namespace osu.Game.Tests.Visual.Online
private static readonly APIUser user_with_missing_values = new APIUser private static readonly APIUser user_with_missing_values = new APIUser
{ {
Id = 8, Id = 8,
MonthlyPlaycounts = new[] MonthlyPlayCounts = new[]
{ {
new APIUserHistoryCount { Date = new DateTime(2020, 1, 1), Count = 100 }, new APIUserHistoryCount { Date = new DateTime(2020, 1, 1), Count = 100 },
new APIUserHistoryCount { Date = new DateTime(2020, 7, 1), Count = 200 } new APIUserHistoryCount { Date = new DateTime(2020, 7, 1), Count = 200 }

View File

@ -1,38 +1,27 @@
// 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.Collections.Generic;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Overlays.Rankings.Tables; using osu.Game.Overlays.Rankings.Tables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Online.API.Requests;
using osu.Game.Rulesets;
using System.Threading; using System.Threading;
using osu.Game.Online.API;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Taiko;
using osu.Game.Rulesets.Catch;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.Rankings; using osu.Game.Users;
namespace osu.Game.Tests.Visual.Online namespace osu.Game.Tests.Visual.Online
{ {
public class TestSceneRankingsTables : OsuTestScene public class TestSceneRankingsTables : OsuTestScene
{ {
protected override bool UseOnlineAPI => true;
[Resolved]
private IAPIProvider api { get; set; }
[Cached] [Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
private readonly BasicScrollContainer scrollFlow; private readonly BasicScrollContainer scrollFlow;
private readonly LoadingLayer loading; private readonly LoadingLayer loading;
private CancellationTokenSource cancellationToken; private CancellationTokenSource cancellationToken;
private APIRequest request;
public TestSceneRankingsTables() public TestSceneRankingsTables()
{ {
@ -53,73 +42,120 @@ namespace osu.Game.Tests.Visual.Online
{ {
base.LoadComplete(); base.LoadComplete();
AddStep("Osu performance", () => createPerformanceTable(new OsuRuleset().RulesetInfo, null)); AddStep("User performance", createPerformanceTable);
AddStep("Mania scores", () => createScoreTable(new ManiaRuleset().RulesetInfo)); AddStep("User scores", createScoreTable);
AddStep("Taiko country scores", () => createCountryTable(new TaikoRuleset().RulesetInfo)); AddStep("Country scores", createCountryTable);
AddStep("Catch US performance page 10", () => createPerformanceTable(new CatchRuleset().RulesetInfo, "US", 10));
AddStep("Osu spotlight table (chart 271)", () => createSpotlightTable(new OsuRuleset().RulesetInfo, 271));
} }
private void createCountryTable(RulesetInfo ruleset, int page = 1) private void createCountryTable()
{ {
onLoadStarted(); onLoadStarted();
request = new GetCountryRankingsRequest(ruleset, page); var countries = new List<CountryStatistics>
((GetCountryRankingsRequest)request).Success += rankings => Schedule(() =>
{ {
var table = new CountriesTable(page, rankings.Countries); new CountryStatistics
loadTable(table); {
}); Country = new Country { FlagName = "US", FullName = "United States" },
FlagName = "US",
ActiveUsers = 2_972_623,
PlayCount = 3_086_515_743,
RankedScore = 449_407_643_332_546,
Performance = 371_974_024
},
new CountryStatistics
{
Country = new Country { FlagName = "RU", FullName = "Russian Federation" },
FlagName = "RU",
ActiveUsers = 1_609_989,
PlayCount = 1_637_052_841,
RankedScore = 221_660_827_473_004,
Performance = 163_426_476
}
};
api.Queue(request); var table = new CountriesTable(1, countries);
loadTable(table);
} }
private void createPerformanceTable(RulesetInfo ruleset, string country, int page = 1) private static List<UserStatistics> createUserStatistics() => new List<UserStatistics>
{
new UserStatistics
{
User = new APIUser
{
Username = "first active user",
Country = new Country { FlagName = "JP" },
Active = true,
},
Accuracy = 0.9972,
PlayCount = 233_215,
TotalScore = 983_231_234_656,
RankedScore = 593_231_345_897,
PP = 23_934,
GradesCount = new UserStatistics.Grades
{
SS = 35_132,
S = 23_345,
A = 12_234
}
},
new UserStatistics
{
User = new APIUser
{
Username = "inactive user",
Country = new Country { FlagName = "AU" },
Active = false,
},
Accuracy = 0.9831,
PlayCount = 195_342,
TotalScore = 683_231_234_656,
RankedScore = 393_231_345_897,
PP = 20_934,
GradesCount = new UserStatistics.Grades
{
SS = 32_132,
S = 20_345,
A = 9_234
}
},
new UserStatistics
{
User = new APIUser
{
Username = "second active user",
Country = new Country { FlagName = "PL" },
Active = true,
},
Accuracy = 0.9584,
PlayCount = 100_903,
TotalScore = 97_242_983_434,
RankedScore = 3_156_345_897,
PP = 9_568,
GradesCount = new UserStatistics.Grades
{
SS = 13_152,
S = 24_375,
A = 9_960
}
},
};
private void createPerformanceTable()
{ {
onLoadStarted(); onLoadStarted();
loadTable(new PerformanceTable(1, createUserStatistics()));
request = new GetUserRankingsRequest(ruleset, country: country, page: page);
((GetUserRankingsRequest)request).Success += rankings => Schedule(() =>
{
var table = new PerformanceTable(page, rankings.Users);
loadTable(table);
});
api.Queue(request);
} }
private void createScoreTable(RulesetInfo ruleset, int page = 1) private void createScoreTable()
{ {
onLoadStarted(); onLoadStarted();
loadTable(new ScoresTable(1, createUserStatistics()));
request = new GetUserRankingsRequest(ruleset, UserRankingsType.Score, page);
((GetUserRankingsRequest)request).Success += rankings => Schedule(() =>
{
var table = new ScoresTable(page, rankings.Users);
loadTable(table);
});
api.Queue(request);
}
private void createSpotlightTable(RulesetInfo ruleset, int spotlight)
{
onLoadStarted();
request = new GetSpotlightRankingsRequest(ruleset, spotlight, RankingsSortCriteria.All);
((GetSpotlightRankingsRequest)request).Success += rankings => Schedule(() =>
{
var table = new ScoresTable(1, rankings.Users);
loadTable(table);
});
api.Queue(request);
} }
private void onLoadStarted() private void onLoadStarted()
{ {
loading.Show(); loading.Show();
request?.Cancel();
cancellationToken?.Cancel(); cancellationToken?.Cancel();
cancellationToken = new CancellationTokenSource(); cancellationToken = new CancellationTokenSource();
} }

View File

@ -0,0 +1,57 @@
// 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 System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing;
using osu.Game.Overlays.BeatmapSet.Scores;
namespace osu.Game.Tests.Visual.Online
{
public class TestSceneScoreboardTime : OsuTestScene
{
private StopwatchClock stopwatch;
[Test]
public void TestVariousUnits()
{
AddStep("create various scoreboard times", () => Child = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Clock = new FramedClock(stopwatch = new StopwatchClock()), // prevent time from naturally elapsing.
Direction = FillDirection.Vertical,
ChildrenEnumerable = testCases.Select(dateTime => new ScoreboardTime(dateTime, 24).With(time => time.Anchor = time.Origin = Anchor.TopCentre))
});
AddStep("start stopwatch", () => stopwatch.Start());
}
private static IEnumerable<DateTimeOffset> testCases => new[]
{
DateTimeOffset.Now,
DateTimeOffset.Now.AddSeconds(-1),
DateTimeOffset.Now.AddSeconds(-25),
DateTimeOffset.Now.AddSeconds(-59),
DateTimeOffset.Now.AddMinutes(-1),
DateTimeOffset.Now.AddMinutes(-25),
DateTimeOffset.Now.AddMinutes(-59),
DateTimeOffset.Now.AddHours(-1),
DateTimeOffset.Now.AddHours(-13),
DateTimeOffset.Now.AddHours(-23),
DateTimeOffset.Now.AddDays(-1),
DateTimeOffset.Now.AddDays(-6),
DateTimeOffset.Now.AddDays(-16),
DateTimeOffset.Now.AddMonths(-1),
DateTimeOffset.Now.AddMonths(-11),
DateTimeOffset.Now.AddYears(-1),
DateTimeOffset.Now.AddYears(-5)
};
}
}

View File

@ -309,8 +309,8 @@ namespace osu.Game.Tests.Visual.Online
private class TestStandAloneChatDisplay : StandAloneChatDisplay private class TestStandAloneChatDisplay : StandAloneChatDisplay
{ {
public TestStandAloneChatDisplay(bool textbox = false) public TestStandAloneChatDisplay(bool textBox = false)
: base(textbox) : base(textBox)
{ {
} }

View File

@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.Playlists
{ {
const string not_found_prefix = "beatmaps not found:"; const string not_found_prefix = "beatmaps not found:";
string errorMesage = null; string errorMessage = null;
AddStep("setup", () => AddStep("setup", () =>
{ {
@ -96,9 +96,9 @@ namespace osu.Game.Tests.Visual.Playlists
SelectedRoom.Value.Name.Value = "Test Room"; SelectedRoom.Value.Name.Value = "Test Room";
SelectedRoom.Value.Playlist.Add(new PlaylistItem { Beatmap = { Value = beatmap } }); SelectedRoom.Value.Playlist.Add(new PlaylistItem { Beatmap = { Value = beatmap } });
errorMesage = $"{not_found_prefix} {beatmap.OnlineID}"; errorMessage = $"{not_found_prefix} {beatmap.OnlineID}";
RoomManager.CreateRequested = _ => errorMesage; RoomManager.CreateRequested = _ => errorMessage;
}); });
AddAssert("error not displayed", () => !settings.ErrorText.IsPresent); AddAssert("error not displayed", () => !settings.ErrorText.IsPresent);
@ -107,7 +107,7 @@ namespace osu.Game.Tests.Visual.Playlists
AddStep("create room", () => settings.ApplyButton.Action.Invoke()); AddStep("create room", () => settings.ApplyButton.Action.Invoke());
AddAssert("error displayed", () => settings.ErrorText.IsPresent); AddAssert("error displayed", () => settings.ErrorText.IsPresent);
AddAssert("error has custom text", () => settings.ErrorText.Text != errorMesage); AddAssert("error has custom text", () => settings.ErrorText.Text != errorMessage);
AddAssert("playlist item marked invalid", () => !SelectedRoom.Value.Playlist[0].Valid.Value); AddAssert("playlist item marked invalid", () => !SelectedRoom.Value.Playlist[0].Valid.Value);
} }

View File

@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -142,7 +143,7 @@ namespace osu.Game.Tests.Visual.Playlists
modifiedBeatmap.HitObjects.Clear(); modifiedBeatmap.HitObjects.Clear();
modifiedBeatmap.HitObjects.Add(new HitCircle { StartTime = 5000 }); modifiedBeatmap.HitObjects.Add(new HitCircle { StartTime = 5000 });
manager.Import(modifiedBeatmap.BeatmapInfo.BeatmapSet).Wait(); manager.Import(modifiedBeatmap.BeatmapInfo.BeatmapSet).WaitSafely();
}); });
// Create the room using the real beatmap values. // Create the room using the real beatmap values.
@ -184,7 +185,7 @@ namespace osu.Game.Tests.Visual.Playlists
}, },
}; };
manager.Import(originalBeatmap.BeatmapInfo.BeatmapSet).Wait(); manager.Import(originalBeatmap.BeatmapInfo.BeatmapSet).WaitSafely();
}); });
AddUntilStep("match has correct beatmap", () => realHash == match.Beatmap.Value.BeatmapInfo.MD5Hash); AddUntilStep("match has correct beatmap", () => realHash == match.Beatmap.Value.BeatmapInfo.MD5Hash);
@ -201,7 +202,7 @@ namespace osu.Game.Tests.Visual.Playlists
}); });
} }
private void importBeatmap() => AddStep("import beatmap", () => importedBeatmap = manager.Import(CreateBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapSet).Result); private void importBeatmap() => AddStep("import beatmap", () => importedBeatmap = manager.Import(CreateBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapSet).GetResultSafely());
private class TestPlaylistsRoomSubScreen : PlaylistsRoomSubScreen private class TestPlaylistsRoomSubScreen : PlaylistsRoomSubScreen
{ {

View File

@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.Settings
new Box new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = colours.GreySeafoam Colour = colours.GreySeaFoam
}, },
restoreDefaultValueButton = new RestoreDefaultValueButton<float> restoreDefaultValueButton = new RestoreDefaultValueButton<float>
{ {

View File

@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual.Settings
}; };
[SettingSource("Sample number textbox", "Textbox number entry", SettingControlType = typeof(SettingsNumberBox))] [SettingSource("Sample number textbox", "Textbox number entry", SettingControlType = typeof(SettingsNumberBox))]
public Bindable<int?> IntTextboxBindable { get; } = new Bindable<int?> public Bindable<int?> IntTextBoxBindable { get; } = new Bindable<int?>
{ {
Default = null, Default = null,
Value = null Value = null

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -74,7 +75,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"Set beatmap", () => AddStep(@"Set beatmap", () =>
{ {
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
beatmapInfo = beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps.First(); beatmapInfo = beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps.First();
leaderboard.BeatmapInfo = beatmapInfo; leaderboard.BeatmapInfo = beatmapInfo;
@ -175,7 +176,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"Load new scores via manager", () => AddStep(@"Load new scores via manager", () =>
{ {
foreach (var score in generateSampleScores(beatmapInfo())) foreach (var score in generateSampleScores(beatmapInfo()))
scoreManager.Import(score).Wait(); scoreManager.Import(score).WaitSafely();
}); });
} }

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Extensions; using osu.Game.Extensions;
@ -181,7 +182,7 @@ namespace osu.Game.Tests.Visual.SongSelect
beatmap.DifficultyName = $"SR{i + 1}"; beatmap.DifficultyName = $"SR{i + 1}";
} }
return Game.BeatmapManager.Import(beatmapSet).Result.Value; return Game.BeatmapManager.Import(beatmapSet).GetResultSafely().Value;
} }
private bool ensureAllBeatmapSetsImported(IEnumerable<BeatmapSetInfo> beatmapSets) => beatmapSets.All(set => set != null); private bool ensureAllBeatmapSetsImported(IEnumerable<BeatmapSetInfo> beatmapSets) => beatmapSets.All(set => set != null);

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory)); Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, Resources, host, Beatmap.Default));
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
base.Content.AddRange(new Drawable[] base.Content.AddRange(new Drawable[]
{ {

View File

@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -256,7 +257,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("import multi-ruleset map", () => AddStep("import multi-ruleset map", () =>
{ {
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray(); var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
manager.Import(TestResources.CreateTestBeatmapSetInfo(rulesets: usableRulesets)).Wait(); manager.Import(TestResources.CreateTestBeatmapSetInfo(rulesets: usableRulesets)).WaitSafely();
}); });
} }
else else
@ -670,7 +671,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("import multi-ruleset map", () => AddStep("import multi-ruleset map", () =>
{ {
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray(); var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).Wait(); manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).WaitSafely();
}); });
int previousSetID = 0; int previousSetID = 0;
@ -710,7 +711,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("import multi-ruleset map", () => AddStep("import multi-ruleset map", () =>
{ {
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray(); var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).Wait(); manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).WaitSafely();
}); });
DrawableCarouselBeatmapSet set = null; DrawableCarouselBeatmapSet set = null;
@ -759,7 +760,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("import huge difficulty count map", () => AddStep("import huge difficulty count map", () =>
{ {
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray(); var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
imported = manager.Import(TestResources.CreateTestBeatmapSetInfo(50, usableRulesets)).Result.Value; imported = manager.Import(TestResources.CreateTestBeatmapSetInfo(50, usableRulesets)).GetResultSafely().Value;
}); });
AddStep("select the first beatmap of import", () => Beatmap.Value = manager.GetWorkingBeatmap(imported.Beatmaps.First())); AddStep("select the first beatmap of import", () => Beatmap.Value = manager.GetWorkingBeatmap(imported.Beatmaps.First()));
@ -868,7 +869,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private void addRulesetImportStep(int id) => AddStep($"import test map for ruleset {id}", () => importForRuleset(id)); private void addRulesetImportStep(int id) => AddStep($"import test map for ruleset {id}", () => importForRuleset(id));
private void importForRuleset(int id) => manager.Import(TestResources.CreateTestBeatmapSetInfo(3, rulesets.AvailableRulesets.Where(r => r.OnlineID == id).ToArray())).Wait(); private void importForRuleset(int id) => manager.Import(TestResources.CreateTestBeatmapSetInfo(3, rulesets.AvailableRulesets.Where(r => r.OnlineID == id).ToArray())).WaitSafely();
private void checkMusicPlaying(bool playing) => private void checkMusicPlaying(bool playing) =>
AddUntilStep($"music {(playing ? "" : "not ")}playing", () => music.IsPlaying == playing); AddUntilStep($"music {(playing ? "" : "not ")}playing", () => music.IsPlaying == playing);
@ -898,7 +899,7 @@ namespace osu.Game.Tests.Visual.SongSelect
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray(); var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
manager.Import(TestResources.CreateTestBeatmapSetInfo(difficultyCountPerSet, usableRulesets)).Wait(); manager.Import(TestResources.CreateTestBeatmapSetInfo(difficultyCountPerSet, usableRulesets)).WaitSafely();
}); });
} }

View File

@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Cursor;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -85,7 +86,7 @@ namespace osu.Game.Tests.Visual.UserInterface
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default)); dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, ContextFactory, Scheduler)); dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, ContextFactory, Scheduler));
beatmapInfo = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).Result.Value.Beatmaps[0]; beatmapInfo = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).GetResultSafely().Value.Beatmaps[0];
for (int i = 0; i < 50; i++) for (int i = 0; i < 50; i++)
{ {
@ -101,7 +102,7 @@ namespace osu.Game.Tests.Visual.UserInterface
User = new APIUser { Username = "TestUser" }, User = new APIUser { Username = "TestUser" },
}; };
importedScores.Add(scoreManager.Import(score).Result.Value); importedScores.Add(scoreManager.Import(score).GetResultSafely().Value);
} }
return dependencies; return dependencies;

View File

@ -29,10 +29,10 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("Display toast with lengthy text", () => osd.Display(new LengthyToast())); AddStep("Display toast with lengthy text", () => osd.Display(new LengthyToast()));
AddAssert("Toast width is greater than 240", () => osd.Child.Width > 240); AddAssert("Toast width is greater than 240", () => osd.Child.Width > 240);
AddRepeatStep("Change toggle (no bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingNoKeybind), 2); AddRepeatStep("Change toggle (no bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingNoKeyBind), 2);
AddRepeatStep("Change toggle (with bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingWithKeybind), 2); AddRepeatStep("Change toggle (with bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingWithKeyBind), 2);
AddRepeatStep("Change enum (no bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingNoKeybind), 3); AddRepeatStep("Change enum (no bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingNoKeyBind), 3);
AddRepeatStep("Change enum (with bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingWithKeybind), 3); AddRepeatStep("Change enum (with bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingWithKeyBind), 3);
} }
private class TestConfigManager : ConfigManager<TestConfigSetting> private class TestConfigManager : ConfigManager<TestConfigSetting>
@ -44,10 +44,10 @@ namespace osu.Game.Tests.Visual.UserInterface
protected override void InitialiseDefaults() protected override void InitialiseDefaults()
{ {
SetDefault(TestConfigSetting.ToggleSettingNoKeybind, false); SetDefault(TestConfigSetting.ToggleSettingNoKeyBind, false);
SetDefault(TestConfigSetting.EnumSettingNoKeybind, EnumSetting.Setting1); SetDefault(TestConfigSetting.EnumSettingNoKeyBind, EnumSetting.Setting1);
SetDefault(TestConfigSetting.ToggleSettingWithKeybind, false); SetDefault(TestConfigSetting.ToggleSettingWithKeyBind, false);
SetDefault(TestConfigSetting.EnumSettingWithKeybind, EnumSetting.Setting1); SetDefault(TestConfigSetting.EnumSettingWithKeyBind, EnumSetting.Setting1);
base.InitialiseDefaults(); base.InitialiseDefaults();
} }
@ -64,10 +64,10 @@ namespace osu.Game.Tests.Visual.UserInterface
public override TrackedSettings CreateTrackedSettings() => new TrackedSettings public override TrackedSettings CreateTrackedSettings() => new TrackedSettings
{ {
new TrackedSetting<bool>(TestConfigSetting.ToggleSettingNoKeybind, b => new SettingDescription(b, "toggle setting with no keybind", b ? "enabled" : "disabled")), new TrackedSetting<bool>(TestConfigSetting.ToggleSettingNoKeyBind, b => new SettingDescription(b, "toggle setting with no keybind", b ? "enabled" : "disabled")),
new TrackedSetting<EnumSetting>(TestConfigSetting.EnumSettingNoKeybind, v => new SettingDescription(v, "enum setting with no keybind", v.ToString())), new TrackedSetting<EnumSetting>(TestConfigSetting.EnumSettingNoKeyBind, v => new SettingDescription(v, "enum setting with no keybind", v.ToString())),
new TrackedSetting<bool>(TestConfigSetting.ToggleSettingWithKeybind, b => new SettingDescription(b, "toggle setting with keybind", b ? "enabled" : "disabled", "fake keybind")), new TrackedSetting<bool>(TestConfigSetting.ToggleSettingWithKeyBind, b => new SettingDescription(b, "toggle setting with keybind", b ? "enabled" : "disabled", "fake keybind")),
new TrackedSetting<EnumSetting>(TestConfigSetting.EnumSettingWithKeybind, v => new SettingDescription(v, "enum setting with keybind", v.ToString(), "fake keybind")), new TrackedSetting<EnumSetting>(TestConfigSetting.EnumSettingWithKeyBind, v => new SettingDescription(v, "enum setting with keybind", v.ToString(), "fake keybind")),
}; };
protected override void PerformLoad() protected override void PerformLoad()
@ -79,10 +79,10 @@ namespace osu.Game.Tests.Visual.UserInterface
private enum TestConfigSetting private enum TestConfigSetting
{ {
ToggleSettingNoKeybind, ToggleSettingNoKeyBind,
EnumSettingNoKeybind, EnumSettingNoKeyBind,
ToggleSettingWithKeybind, ToggleSettingWithKeyBind,
EnumSettingWithKeybind EnumSettingWithKeyBind
} }
private enum EnumSetting private enum EnumSetting

View File

@ -62,6 +62,6 @@ namespace osu.Game.Tests.Visual.UserInterface
} }
private void clearTextboxes(IEnumerable<OsuTextBox> textBoxes) => AddStep("clear textbox", () => textBoxes.ForEach(textBox => textBox.Text = null)); private void clearTextboxes(IEnumerable<OsuTextBox> textBoxes) => AddStep("clear textbox", () => textBoxes.ForEach(textBox => textBox.Text = null));
private void expectedValue(IEnumerable<OsuTextBox> textBoxes, string value) => AddAssert("expected textbox value", () => textBoxes.All(textbox => textbox.Text == value)); private void expectedValue(IEnumerable<OsuTextBox> textBoxes, string value) => AddAssert("expected textbox value", () => textBoxes.All(textBox => textBox.Text == value));
} }
} }

View File

@ -0,0 +1,79 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface.PageSelector;
using osu.Game.Overlays;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestScenePageSelector : OsuTestScene
{
[Cached]
private OverlayColourProvider provider { get; } = new OverlayColourProvider(OverlayColourScheme.Green);
private readonly PageSelector pageSelector;
public TestScenePageSelector()
{
AddRange(new Drawable[]
{
pageSelector = new PageSelector
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
});
}
[Test]
public void TestOmittedPages()
{
setAvailablePages(100);
selectPageIndex(0);
checkVisiblePageNumbers(new[] { 1, 2, 3, 100 });
selectPageIndex(6);
checkVisiblePageNumbers(new[] { 1, 5, 6, 7, 8, 9, 100 });
selectPageIndex(49);
checkVisiblePageNumbers(new[] { 1, 48, 49, 50, 51, 52, 100 });
selectPageIndex(99);
checkVisiblePageNumbers(new[] { 1, 98, 99, 100 });
}
[Test]
public void TestResetCurrentPage()
{
setAvailablePages(10);
selectPageIndex(6);
setAvailablePages(11);
AddAssert("Page 1 is current", () => pageSelector.CurrentPage.Value == 0);
}
[Test]
public void TestOutOfBoundsSelection()
{
setAvailablePages(10);
selectPageIndex(11);
AddAssert("Page 10 is current", () => pageSelector.CurrentPage.Value == pageSelector.AvailablePages.Value - 1);
selectPageIndex(-1);
AddAssert("Page 1 is current", () => pageSelector.CurrentPage.Value == 0);
}
private void checkVisiblePageNumbers(int[] expected) => AddAssert($"Sequence is {string.Join(',', expected.Select(i => i.ToString()))}", () => pageSelector.ChildrenOfType<PageSelectorPageButton>().Select(p => p.PageNumber).SequenceEqual(expected));
private void selectPageIndex(int pageIndex) =>
AddStep($"Select page {pageIndex}", () => pageSelector.CurrentPage.Value = pageIndex);
private void setAvailablePages(int availablePages) =>
AddStep($"Set available pages to {availablePages}", () => pageSelector.AvailablePages.Value = availablePages);
}
}

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -31,7 +32,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
this.api = api; this.api = api;
testBeatmap = ImportBeatmapTest.LoadOszIntoOsu(osu).Result; testBeatmap = ImportBeatmapTest.LoadOszIntoOsu(osu).GetResultSafely();
} }
[Test] [Test]

View File

@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.UserInterface
new Box new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = colours.GreySeafoam Colour = colours.GreySeaFoam
}, },
CreateContent() CreateContent()
}); });

View File

@ -36,7 +36,7 @@ namespace osu.Game.Tournament.Tests.NonVisual
TournamentStorage storage = (TournamentStorage)osu.Dependencies.Get<Storage>(); TournamentStorage storage = (TournamentStorage)osu.Dependencies.Get<Storage>();
FileBasedIPC ipc = null; FileBasedIPC ipc = null;
WaitForOrAssert(() => (ipc = osu.Dependencies.Get<MatchIPCInfo>() as FileBasedIPC) != null, @"ipc could not be populated in a reasonable amount of time"); WaitForOrAssert(() => (ipc = osu.Dependencies.Get<MatchIPCInfo>() as FileBasedIPC)?.IsLoaded == true, @"ipc could not be populated in a reasonable amount of time");
Assert.True(ipc.SetIPCLocation(testStableInstallDirectory)); Assert.True(ipc.SetIPCLocation(testStableInstallDirectory));
Assert.True(storage.AllTournaments.Exists("stable.json")); Assert.True(storage.AllTournaments.Exists("stable.json"));

View File

@ -85,14 +85,14 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
private ScrollState scrollState; private ScrollState scrollState;
private void setScrollState(ScrollState newstate) private void setScrollState(ScrollState newState)
{ {
if (scrollState == newstate) if (scrollState == newState)
return; return;
delayedStateChangeDelegate?.Cancel(); delayedStateChangeDelegate?.Cancel();
switch (scrollState = newstate) switch (scrollState = newState)
{ {
case ScrollState.Scrolling: case ScrollState.Scrolling:
resetSelected(); resetSelected();

View File

@ -208,10 +208,10 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
{ {
if (Match.Round.Value == null) return; if (Match.Round.Value == null) return;
int instaWinAmount = Match.Round.Value.BestOf.Value / 2; int instantWinAmount = Match.Round.Value.BestOf.Value / 2;
Match.Completed.Value = Match.Round.Value.BestOf.Value > 0 Match.Completed.Value = Match.Round.Value.BestOf.Value > 0
&& (Match.Team1Score.Value + Match.Team2Score.Value >= Match.Round.Value.BestOf.Value || Match.Team1Score.Value > instaWinAmount || Match.Team2Score.Value > instaWinAmount); && (Match.Team1Score.Value + Match.Team2Score.Value >= Match.Round.Value.BestOf.Value || Match.Team1Score.Value > instantWinAmount || Match.Team2Score.Value > instantWinAmount);
} }
protected override void LoadComplete() protected override void LoadComplete()

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