diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 9e9af23b27..814fc81f51 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -5,7 +5,7 @@ updates:
schedule:
interval: monthly
time: "17:00"
- open-pull-requests-limit: 99
+ open-pull-requests-limit: 0 # disabled until https://github.com/dependabot/dependabot-core/issues/369 is resolved.
ignore:
- dependency-name: Microsoft.EntityFrameworkCore.Design
versions:
diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Mods/EmptyFreeformModAutoplay.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Mods/EmptyFreeformModAutoplay.cs
index f705009d18..d4496a24fd 100644
--- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Mods/EmptyFreeformModAutoplay.cs
+++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Mods/EmptyFreeformModAutoplay.cs
@@ -3,10 +3,10 @@
using System.Collections.Generic;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.EmptyFreeform.Replays;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Rulesets.EmptyFreeform.Mods
{
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.EmptyFreeform.Mods
{
ScoreInfo = new ScoreInfo
{
- User = new User { Username = "sample" },
+ User = new APIUser { Username = "sample" },
},
Replay = new EmptyFreeformAutoGenerator(beatmap).Generate(),
};
diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Mods/PippidonModAutoplay.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Mods/PippidonModAutoplay.cs
index 4565c97d1a..6e1fe42ee2 100644
--- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Mods/PippidonModAutoplay.cs
+++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Mods/PippidonModAutoplay.cs
@@ -3,10 +3,10 @@
using System.Collections.Generic;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Pippidon.Replays;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Rulesets.Pippidon.Mods
{
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Pippidon.Mods
{
ScoreInfo = new ScoreInfo
{
- User = new User { Username = "sample" },
+ User = new APIUser { Username = "sample" },
},
Replay = new PippidonAutoGenerator(beatmap).Generate(),
};
diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Mods/EmptyScrollingModAutoplay.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Mods/EmptyScrollingModAutoplay.cs
index 431994e098..c5bacb522f 100644
--- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Mods/EmptyScrollingModAutoplay.cs
+++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Mods/EmptyScrollingModAutoplay.cs
@@ -5,8 +5,8 @@ using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.EmptyScrolling.Replays;
using osu.Game.Scoring;
-using osu.Game.Users;
using System.Collections.Generic;
+using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Rulesets.EmptyScrolling.Mods
{
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.EmptyScrolling.Mods
{
ScoreInfo = new ScoreInfo
{
- User = new User { Username = "sample" },
+ User = new APIUser { Username = "sample" },
},
Replay = new EmptyScrollingAutoGenerator(beatmap).Generate(),
};
diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Mods/PippidonModAutoplay.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Mods/PippidonModAutoplay.cs
index 4565c97d1a..6e1fe42ee2 100644
--- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Mods/PippidonModAutoplay.cs
+++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Mods/PippidonModAutoplay.cs
@@ -3,10 +3,10 @@
using System.Collections.Generic;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Pippidon.Replays;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Rulesets.Pippidon.Mods
{
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Pippidon.Mods
{
ScoreInfo = new ScoreInfo
{
- User = new User { Username = "sample" },
+ User = new APIUser { Username = "sample" },
},
Replay = new PippidonAutoGenerator(beatmap).Generate(),
};
diff --git a/osu.Android.props b/osu.Android.props
index 4f9f83f199..752eb160ed 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,7 +52,7 @@
-
+
diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs
index e2b40e9dc6..e1e7e6ad18 100644
--- a/osu.Desktop/DiscordRichPresence.cs
+++ b/osu.Desktop/DiscordRichPresence.cs
@@ -11,10 +11,10 @@ using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Game.Configuration;
using osu.Game.Online.API;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets;
using osu.Game.Users;
using LogLevel = osu.Framework.Logging.LogLevel;
-using User = osu.Game.Users.User;
namespace osu.Desktop
{
@@ -27,7 +27,7 @@ namespace osu.Desktop
[Resolved]
private IBindable ruleset { get; set; }
- private IBindable user;
+ private IBindable user;
private readonly IBindable status = new Bindable();
private readonly IBindable activity = new Bindable();
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs b/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs
index 6f3e6763bd..11fffb31de 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs
@@ -3,10 +3,10 @@
using System.Collections.Generic;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Catch.Replays;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Rulesets.Catch.Mods
{
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Catch.Mods
{
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList mods) => new Score
{
- ScoreInfo = new ScoreInfo { User = new User { Username = "osu!salad" } },
+ ScoreInfo = new ScoreInfo { User = new APIUser { Username = "osu!salad" } },
Replay = new CatchAutoGenerator(beatmap).Generate(),
};
}
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModCinema.cs b/osu.Game.Rulesets.Catch/Mods/CatchModCinema.cs
index 1b7d254321..6d2286b957 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModCinema.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModCinema.cs
@@ -3,11 +3,11 @@
using System.Collections.Generic;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Replays;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Rulesets.Catch.Mods
{
@@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Mods
{
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList mods) => new Score
{
- ScoreInfo = new ScoreInfo { User = new User { Username = "osu!salad" } },
+ ScoreInfo = new ScoreInfo { User = new APIUser { Username = "osu!salad" } },
Replay = new CatchAutoGenerator(beatmap).Generate(),
};
}
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs
index 86f667466f..1504c868d0 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs
@@ -3,11 +3,11 @@
using System.Collections.Generic;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Replays;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Rulesets.Mania.Mods
{
@@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Mods
{
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList mods) => new Score
{
- ScoreInfo = new ScoreInfo { User = new User { Username = "osu!topus" } },
+ ScoreInfo = new ScoreInfo { User = new APIUser { Username = "osu!topus" } },
Replay = new ManiaAutoGenerator((ManiaBeatmap)beatmap).Generate(),
};
}
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModCinema.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModCinema.cs
index 1c06bb389b..4f1276946b 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModCinema.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModCinema.cs
@@ -3,12 +3,12 @@
using System.Collections.Generic;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Replays;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Rulesets.Mania.Mods
{
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Mods
{
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList mods) => new Score
{
- ScoreInfo = new ScoreInfo { User = new User { Username = "osu!topus" } },
+ ScoreInfo = new ScoreInfo { User = new APIUser { Username = "osu!topus" } },
Replay = new ManiaAutoGenerator((ManiaBeatmap)beatmap).Generate(),
};
}
diff --git a/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs
index 7cd06c5225..b0e173e752 100644
--- a/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs
+++ b/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs
@@ -15,13 +15,13 @@ namespace osu.Game.Rulesets.Osu.Tests
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Osu";
- [TestCase(6.5295339534769958d, "diffcalc-test")]
- [TestCase(1.1514260533755143d, "zero-length-sliders")]
+ [TestCase(6.6975550434910005d, "diffcalc-test")]
+ [TestCase(1.4670676815251105d, "zero-length-sliders")]
public void Test(double expected, string name)
=> base.Test(expected, name);
- [TestCase(9.047752485219954d, "diffcalc-test")]
- [TestCase(1.3985711787077566d, "zero-length-sliders")]
+ [TestCase(8.9389769779826267d, "diffcalc-test")]
+ [TestCase(1.7786917985891204d, "zero-length-sliders")]
public void TestClockRateAdjusted(double expected, string name)
=> Test(expected, name, new OsuModDoubleTime());
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneMissHitWindowJudgements.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneMissHitWindowJudgements.cs
index a5629119b6..840d871b7b 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneMissHitWindowJudgements.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneMissHitWindowJudgements.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using NUnit.Framework;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Replays;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Beatmaps;
@@ -14,7 +15,6 @@ using osu.Game.Rulesets.Osu.Scoring;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Tests.Visual;
-using osu.Game.Users;
using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
@@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Osu.Tests
{
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList mods) => new Score
{
- ScoreInfo = new ScoreInfo { User = new User { Username = "Autoplay" } },
+ ScoreInfo = new ScoreInfo { User = new APIUser { Username = "Autoplay" } },
Replay = new MissingAutoGenerator(beatmap, mods).Generate()
};
}
diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
index 4bca87204a..a9d9ff6985 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
@@ -54,7 +54,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (mods.Any(h => h is OsuModRelax))
{
- effectiveMissCount += countOk + countMeh;
+ // As we're adding Oks and Mehs to an approximated number of combo breaks the result can be higher than total hits in specific scenarios (which breaks some calculations) so we need to clamp it.
+ effectiveMissCount = Math.Min(effectiveMissCount + countOk + countMeh, totalHits);
+
multiplier *= 0.6;
}
@@ -109,13 +111,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
- approachRateFactor = Attributes.ApproachRate - 10.33;
+ approachRateFactor = 0.3 * (Attributes.ApproachRate - 10.33);
else if (Attributes.ApproachRate < 8.0)
- approachRateFactor = 0.025 * (8.0 - Attributes.ApproachRate);
+ approachRateFactor = 0.1 * (8.0 - Attributes.ApproachRate);
- double approachRateTotalHitsFactor = 1.0 / (1.0 + Math.Exp(-(0.007 * (totalHits - 400))));
-
- double approachRateBonus = 1.0 + (0.03 + 0.37 * approachRateTotalHitsFactor) * approachRateFactor;
+ aimValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR.
if (mods.Any(m => m is OsuModBlinds))
aimValue *= 1.3 + (totalHits * (0.0016 / (1 + 2 * effectiveMissCount)) * Math.Pow(accuracy, 16)) * (1 - 0.003 * Attributes.DrainRate * Attributes.DrainRate);
@@ -125,10 +125,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
aimValue *= 1.0 + 0.04 * (12.0 - Attributes.ApproachRate);
}
- aimValue *= approachRateBonus;
-
- // Scale the aim value with accuracy _slightly_.
- aimValue *= 0.5 + accuracy / 2.0;
+ aimValue *= accuracy;
// It is important to also consider accuracy difficulty when doing that.
aimValue *= 0.98 + Math.Pow(Attributes.OverallDifficulty, 2) / 2500;
@@ -154,11 +151,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
- approachRateFactor = Attributes.ApproachRate - 10.33;
+ approachRateFactor = 0.3 * (Attributes.ApproachRate - 10.33);
- double approachRateTotalHitsFactor = 1.0 / (1.0 + Math.Exp(-(0.007 * (totalHits - 400))));
-
- speedValue *= 1.0 + (0.03 + 0.37 * approachRateTotalHitsFactor) * approachRateFactor;
+ speedValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR.
if (mods.Any(m => m is OsuModBlinds))
{
@@ -255,7 +250,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
private int calculateEffectiveMissCount()
{
- // guess the number of misses + slider breaks from combo
+ // Guess the number of misses + slider breaks from combo
double comboBasedMissCount = 0.0;
if (Attributes.SliderCount > 0)
@@ -265,7 +260,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
comboBasedMissCount = fullComboThreshold / Math.Max(1.0, scoreMaxCombo);
}
- // we're clamping misscount because since its derived from combo it can be higher than total hits and that breaks some calculations
+ // Clamp misscount since it's derived from combo and can be higher than total hits and that breaks some calculations
comboBasedMissCount = Math.Min(comboBasedMissCount, totalHits);
return Math.Max(countMiss, (int)Math.Floor(comboBasedMissCount));
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs
index 4b90285fd4..cbaad93bed 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
-using System.Linq;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Objects;
@@ -14,6 +13,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
{
private const int normalized_radius = 50; // Change radius to 50 to make 100 the diameter. Easier for mental maths.
private const int min_delta_time = 25;
+ private const float maximum_slider_radius = normalized_radius * 2.4f;
+ private const float assumed_slider_radius = normalized_radius * 1.65f;
protected new OsuHitObject BaseObject => (OsuHitObject)base.BaseObject;
@@ -89,7 +90,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
if (lastObject is Slider lastSlider)
{
computeSliderCursorPosition(lastSlider);
- TravelDistance = lastSlider.LazyTravelDistance * scalingFactor;
+ TravelDistance = lastSlider.LazyTravelDistance;
TravelTime = Math.Max(lastSlider.LazyTravelTime / clockRate, min_delta_time);
MovementTime = Math.Max(StrainTime - TravelTime, min_delta_time);
@@ -99,7 +100,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
// For hitobjects which continue in the direction of the slider, the player will normally follow through the slider,
// such that they're not jumping from the lazy position but rather from very close to (or the end of) the slider.
// In such cases, a leniency is applied by also considering the jump distance from the tail of the slider, and taking the minimum jump distance.
- MovementDistance = Math.Min(JumpDistance, tailJumpDistance);
+ // Additional distance is removed based on position of jump relative to slider follow circle radius.
+ // JumpDistance is the leniency distance beyond the assumed_slider_radius. tailJumpDistance is maximum_slider_radius since the full distance of radial leniency is still possible.
+ MovementDistance = Math.Max(0, Math.Min(JumpDistance - (maximum_slider_radius - assumed_slider_radius), tailJumpDistance - maximum_slider_radius));
}
else
{
@@ -126,37 +129,60 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
if (slider.LazyEndPosition != null)
return;
- slider.LazyEndPosition = slider.StackedPosition;
+ slider.LazyTravelTime = slider.NestedHitObjects[^1].StartTime - slider.StartTime;
- float followCircleRadius = (float)(slider.Radius * 2.4);
- var computeVertex = new Action(t =>
+ double endTimeMin = slider.LazyTravelTime / slider.SpanDuration;
+ if (endTimeMin % 2 >= 1)
+ endTimeMin = 1 - endTimeMin % 1;
+ else
+ endTimeMin %= 1;
+
+ slider.LazyEndPosition = slider.StackedPosition + slider.Path.PositionAt(endTimeMin); // temporary lazy end position until a real result can be derived.
+ var currCursorPosition = slider.StackedPosition;
+ double scalingFactor = normalized_radius / slider.Radius; // lazySliderDistance is coded to be sensitive to scaling, this makes the maths easier with the thresholds being used.
+
+ for (int i = 1; i < slider.NestedHitObjects.Count; i++)
{
- double progress = (t - slider.StartTime) / slider.SpanDuration;
- if (progress % 2 >= 1)
- progress = 1 - progress % 1;
- else
- progress %= 1;
+ var currMovementObj = (OsuHitObject)slider.NestedHitObjects[i];
- // ReSharper disable once PossibleInvalidOperationException (bugged in current r# version)
- var diff = slider.StackedPosition + slider.Path.PositionAt(progress) - slider.LazyEndPosition.Value;
- float dist = diff.Length;
+ Vector2 currMovement = Vector2.Subtract(currMovementObj.StackedPosition, currCursorPosition);
+ double currMovementLength = scalingFactor * currMovement.Length;
- slider.LazyTravelTime = t - slider.StartTime;
+ // Amount of movement required so that the cursor position needs to be updated.
+ double requiredMovement = assumed_slider_radius;
- if (dist > followCircleRadius)
+ if (i == slider.NestedHitObjects.Count - 1)
{
- // The cursor would be outside the follow circle, we need to move it
- diff.Normalize(); // Obtain direction of diff
- dist -= followCircleRadius;
- slider.LazyEndPosition += diff * dist;
- slider.LazyTravelDistance += dist;
- }
- });
+ // The end of a slider has special aim rules due to the relaxed time constraint on position.
+ // There is both a lazy end position as well as the actual end slider position. We assume the player takes the simpler movement.
+ // For sliders that are circular, the lazy end position may actually be farther away than the sliders true end.
+ // This code is designed to prevent buffing situations where lazy end is actually a less efficient movement.
+ Vector2 lazyMovement = Vector2.Subtract((Vector2)slider.LazyEndPosition, currCursorPosition);
- // Skip the head circle
- var scoringTimes = slider.NestedHitObjects.Skip(1).Select(t => t.StartTime);
- foreach (double time in scoringTimes)
- computeVertex(time);
+ if (lazyMovement.Length < currMovement.Length)
+ currMovement = lazyMovement;
+
+ currMovementLength = scalingFactor * currMovement.Length;
+ }
+ else if (currMovementObj is SliderRepeat)
+ {
+ // For a slider repeat, assume a tighter movement threshold to better assess repeat sliders.
+ requiredMovement = normalized_radius;
+ }
+
+ if (currMovementLength > requiredMovement)
+ {
+ // this finds the positional delta from the required radius and the current position, and updates the currCursorPosition accordingly, as well as rewarding distance.
+ currCursorPosition = Vector2.Add(currCursorPosition, Vector2.Multiply(currMovement, (float)((currMovementLength - requiredMovement) / currMovementLength)));
+ currMovementLength *= (currMovementLength - requiredMovement) / currMovementLength;
+ slider.LazyTravelDistance += (float)currMovementLength;
+ }
+
+ if (i == slider.NestedHitObjects.Count - 1)
+ slider.LazyEndPosition = currCursorPosition;
+ }
+
+ slider.LazyTravelDistance *= (float)Math.Pow(1 + slider.RepeatCount / 2.5, 1.0 / 2.5); // Bonus for repeat sliders until a better per nested object strain system can be achieved.
}
private Vector2 getEndCursorPosition(OsuHitObject hitObject)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs
index a054b46366..4c40a49396 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs
@@ -23,8 +23,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
private const double wide_angle_multiplier = 1.5;
private const double acute_angle_multiplier = 2.0;
+ private const double slider_multiplier = 1.5;
+ private const double velocity_change_multiplier = 0.75;
- private double currentStrain = 1;
+ private double currentStrain;
private double skillMultiplier => 23.25;
private double strainDecayBase => 0.15;
@@ -61,7 +63,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
prevVelocity = Math.Max(prevVelocity, movementVelocity + travelVelocity);
}
- double angleBonus = 0;
+ double wideAngleBonus = 0;
+ double acuteAngleBonus = 0;
+ double sliderBonus = 0;
+ double velocityChangeBonus = 0;
+
double aimStrain = currVelocity; // Start strain with regular velocity.
if (Math.Max(osuCurrObj.StrainTime, osuLastObj.StrainTime) < 1.25 * Math.Min(osuCurrObj.StrainTime, osuLastObj.StrainTime)) // If rhythms are the same.
@@ -73,10 +79,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
double lastLastAngle = osuLastLastObj.Angle.Value;
// Rewarding angles, take the smaller velocity as base.
- angleBonus = Math.Min(currVelocity, prevVelocity);
+ double angleBonus = Math.Min(currVelocity, prevVelocity);
- double wideAngleBonus = calcWideAngleBonus(currAngle);
- double acuteAngleBonus = calcAcuteAngleBonus(currAngle);
+ wideAngleBonus = calcWideAngleBonus(currAngle);
+ acuteAngleBonus = calcAcuteAngleBonus(currAngle);
if (osuCurrObj.StrainTime > 100) // Only buff deltaTime exceeding 300 bpm 1/2.
acuteAngleBonus = 0;
@@ -88,14 +94,48 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
* Math.Pow(Math.Sin(Math.PI / 2 * (Math.Clamp(osuCurrObj.JumpDistance, 50, 100) - 50) / 50), 2); // Buff distance exceeding 50 (radius) up to 100 (diameter).
}
- wideAngleBonus *= angleBonus * (1 - Math.Min(wideAngleBonus, Math.Pow(calcWideAngleBonus(lastAngle), 3))); // Penalize wide angles if they're repeated, reducing the penalty as the lastAngle gets more acute.
- acuteAngleBonus *= 0.5 + 0.5 * (1 - Math.Min(acuteAngleBonus, Math.Pow(calcAcuteAngleBonus(lastLastAngle), 3))); // Penalize acute angles if they're repeated, reducing the penalty as the lastLastAngle gets more obtuse.
-
- angleBonus = acuteAngleBonus * acute_angle_multiplier + wideAngleBonus * wide_angle_multiplier; // add the angle buffs together.
+ // Penalize wide angles if they're repeated, reducing the penalty as the lastAngle gets more acute.
+ wideAngleBonus *= angleBonus * (1 - Math.Min(wideAngleBonus, Math.Pow(calcWideAngleBonus(lastAngle), 3)));
+ // Penalize acute angles if they're repeated, reducing the penalty as the lastLastAngle gets more obtuse.
+ acuteAngleBonus *= 0.5 + 0.5 * (1 - Math.Min(acuteAngleBonus, Math.Pow(calcAcuteAngleBonus(lastLastAngle), 3)));
}
}
- aimStrain += angleBonus; // Add in angle bonus.
+ if (Math.Max(prevVelocity, currVelocity) != 0)
+ {
+ // We want to use the average velocity over the whole object when awarding differences, not the individual jump and slider path velocities.
+ prevVelocity = (osuLastObj.JumpDistance + osuLastObj.TravelDistance) / osuLastObj.StrainTime;
+ currVelocity = (osuCurrObj.JumpDistance + osuCurrObj.TravelDistance) / osuCurrObj.StrainTime;
+
+ // Scale with ratio of difference compared to 0.5 * max dist.
+ double distRatio = Math.Pow(Math.Sin(Math.PI / 2 * Math.Abs(prevVelocity - currVelocity) / Math.Max(prevVelocity, currVelocity)), 2);
+
+ // Reward for % distance up to 125 / strainTime for overlaps where velocity is still changing.
+ double overlapVelocityBuff = Math.Min(125 / Math.Min(osuCurrObj.StrainTime, osuLastObj.StrainTime), Math.Abs(prevVelocity - currVelocity));
+
+ // Reward for % distance slowed down compared to previous, paying attention to not award overlap
+ double nonOverlapVelocityBuff = Math.Abs(prevVelocity - currVelocity)
+ // do not award overlap
+ * Math.Pow(Math.Sin(Math.PI / 2 * Math.Min(1, Math.Min(osuCurrObj.JumpDistance, osuLastObj.JumpDistance) / 100)), 2);
+
+ // Choose the largest bonus, multiplied by ratio.
+ velocityChangeBonus = Math.Max(overlapVelocityBuff, nonOverlapVelocityBuff) * distRatio;
+
+ // Penalize for rhythm changes.
+ velocityChangeBonus *= Math.Pow(Math.Min(osuCurrObj.StrainTime, osuLastObj.StrainTime) / Math.Max(osuCurrObj.StrainTime, osuLastObj.StrainTime), 2);
+ }
+
+ if (osuCurrObj.TravelTime != 0)
+ {
+ // Reward sliders based on velocity.
+ sliderBonus = osuCurrObj.TravelDistance / osuCurrObj.TravelTime;
+ }
+
+ // Add in acute angle bonus or wide angle bonus + velocity change bonus, whichever is larger.
+ aimStrain += Math.Max(acuteAngleBonus * acute_angle_multiplier, wideAngleBonus * wide_angle_multiplier + velocityChangeBonus * velocity_change_multiplier);
+
+ // Add in additional slider velocity bonus.
+ aimStrain += sliderBonus * slider_multiplier;
return aimStrain;
}
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs
index e3abe7d700..466f0556ab 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs
@@ -23,7 +23,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
private double strainDecayBase => 0.15;
protected override double DecayWeight => 1.0;
protected override int HistoryLength => 10; // Look back for 10 notes is added for the sake of flashlight calculations.
- private double currentStrain = 1;
+
+ private double currentStrain;
private double strainValueOf(DifficultyHitObject current)
{
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
index cae6b8e01c..24881d9c47 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
@@ -24,8 +24,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
private double skillMultiplier => 1375;
private double strainDecayBase => 0.3;
- private double currentStrain = 1;
- private double currentRhythm = 1;
+ private double currentStrain;
+ private double currentRhythm;
protected override int ReducedSectionCount => 5;
protected override double DifficultyMultiplier => 1.04;
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs
index 652da7123e..106edfb623 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs
@@ -5,10 +5,10 @@ using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Replays;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Rulesets.Osu.Mods
{
@@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList mods) => new Score
{
- ScoreInfo = new ScoreInfo { User = new User { Username = "Autoplay" } },
+ ScoreInfo = new ScoreInfo { User = new APIUser { Username = "Autoplay" } },
Replay = new OsuAutoGenerator(beatmap, mods).Generate()
};
}
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModCinema.cs b/osu.Game.Rulesets.Osu/Mods/OsuModCinema.cs
index df06988b70..f478790134 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModCinema.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModCinema.cs
@@ -5,11 +5,11 @@ using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Replays;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Rulesets.Osu.Mods
{
@@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList mods) => new Score
{
- ScoreInfo = new ScoreInfo { User = new User { Username = "Autoplay" } },
+ ScoreInfo = new ScoreInfo { User = new APIUser { Username = "Autoplay" } },
Replay = new OsuAutoGenerator(beatmap, mods).Generate()
};
}
diff --git a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneEditorSaving.cs b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneEditorSaving.cs
new file mode 100644
index 0000000000..159a64d1ac
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneEditorSaving.cs
@@ -0,0 +1,91 @@
+// Copyright (c) ppy Pty Ltd . 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.Input;
+using osu.Framework.Testing;
+using osu.Framework.Utils;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Edit;
+using osu.Game.Rulesets.Taiko.Beatmaps;
+using osu.Game.Screens.Edit;
+using osu.Game.Screens.Edit.Setup;
+using osu.Game.Screens.Menu;
+using osu.Game.Screens.Select;
+using osu.Game.Tests.Visual;
+using osuTK.Input;
+
+namespace osu.Game.Rulesets.Taiko.Tests.Editor
+{
+ public class TestSceneEditorSaving : OsuGameTestScene
+ {
+ private Screens.Edit.Editor editor => Game.ChildrenOfType().FirstOrDefault();
+
+ private EditorBeatmap editorBeatmap => (EditorBeatmap)editor.Dependencies.Get(typeof(EditorBeatmap));
+
+ ///
+ /// Tests the general expected flow of creating a new beatmap, saving it, then loading it back from song select.
+ /// Emphasis is placed on , since taiko has special handling for it to keep compatibility with stable.
+ ///
+ [Test]
+ public void TestNewBeatmapSaveThenLoad()
+ {
+ AddStep("set default beatmap", () => Game.Beatmap.SetDefault());
+ AddStep("set taiko ruleset", () => Ruleset.Value = new TaikoRuleset().RulesetInfo);
+
+ PushAndConfirm(() => new EditorLoader());
+
+ AddUntilStep("wait for editor load", () => editor?.IsLoaded == true);
+
+ AddUntilStep("wait for metadata screen load", () => editor.ChildrenOfType().FirstOrDefault()?.IsLoaded == true);
+
+ // We intentionally switch away from the metadata screen, else there is a feedback loop with the textbox handling which causes metadata changes below to get overwritten.
+
+ AddStep("Enter compose mode", () => InputManager.Key(Key.F1));
+ AddUntilStep("Wait for compose mode load", () => editor.ChildrenOfType().FirstOrDefault()?.IsLoaded == true);
+
+ AddStep("Set slider multiplier", () => editorBeatmap.Difficulty.SliderMultiplier = 2);
+ AddStep("Set artist and title", () =>
+ {
+ editorBeatmap.BeatmapInfo.Metadata.Artist = "artist";
+ editorBeatmap.BeatmapInfo.Metadata.Title = "title";
+ });
+ AddStep("Set difficulty name", () => editorBeatmap.BeatmapInfo.Version = "difficulty");
+
+ checkMutations();
+
+ AddStep("Save", () => InputManager.Keys(PlatformAction.Save));
+
+ checkMutations();
+
+ AddStep("Exit", () => InputManager.Key(Key.Escape));
+
+ AddUntilStep("Wait for main menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
+
+ PushAndConfirm(() => new PlaySongSelect());
+
+ AddUntilStep("Wait for beatmap selected", () => !Game.Beatmap.IsDefault);
+ AddStep("Open options", () => InputManager.Key(Key.F3));
+ AddStep("Enter editor", () => InputManager.Key(Key.Number5));
+
+ AddUntilStep("Wait for editor load", () => editor != null);
+
+ checkMutations();
+ }
+
+ private void checkMutations()
+ {
+ AddAssert("Beatmap has correct slider multiplier", () =>
+ {
+ // we can only assert value correctness on TaikoMultiplierAppliedDifficulty, because that is the final difficulty converted taiko beatmaps use.
+ // therefore, ensure that we have that difficulty type by calling .CopyFrom(), which is a no-op if the type is already correct.
+ var taikoDifficulty = new TaikoBeatmapConverter.TaikoMultiplierAppliedDifficulty();
+ taikoDifficulty.CopyFrom(editorBeatmap.Difficulty);
+ return Precision.AlmostEquals(taikoDifficulty.SliderMultiplier, 2);
+ });
+ AddAssert("Beatmap has correct metadata", () => editorBeatmap.BeatmapInfo.Metadata.Artist == "artist" && editorBeatmap.BeatmapInfo.Metadata.Title == "title");
+ AddAssert("Beatmap has correct difficulty name", () => editorBeatmap.BeatmapInfo.Version == "difficulty");
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs
index 94dfb67d93..9b2e9fedc5 100644
--- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs
+++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs
@@ -191,7 +191,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
protected override Beatmap CreateBeatmap() => new TaikoBeatmap();
- private class TaikoMultiplierAppliedDifficulty : BeatmapDifficulty
+ internal class TaikoMultiplierAppliedDifficulty : BeatmapDifficulty
{
public TaikoMultiplierAppliedDifficulty(IBeatmapDifficultyInfo difficulty)
{
@@ -209,7 +209,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
{
base.CopyTo(other);
if (!(other is TaikoMultiplierAppliedDifficulty))
- SliderMultiplier /= LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER;
+ other.SliderMultiplier /= LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER;
}
public override void CopyFrom(IBeatmapDifficultyInfo other)
diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModAutoplay.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModAutoplay.cs
index 31d9abf8b2..5832ae3dc1 100644
--- a/osu.Game.Rulesets.Taiko/Mods/TaikoModAutoplay.cs
+++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModAutoplay.cs
@@ -3,10 +3,10 @@
using System.Collections.Generic;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Taiko.Replays;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Rulesets.Taiko.Mods
{
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
{
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList mods) => new Score
{
- ScoreInfo = new ScoreInfo { User = new User { Username = "mekkadosu!" } },
+ ScoreInfo = new ScoreInfo { User = new APIUser { Username = "mekkadosu!" } },
Replay = new TaikoAutoGenerator(beatmap).Generate(),
};
}
diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModCinema.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModCinema.cs
index 00f0c8e321..f76e04a069 100644
--- a/osu.Game.Rulesets.Taiko/Mods/TaikoModCinema.cs
+++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModCinema.cs
@@ -3,11 +3,11 @@
using System.Collections.Generic;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Replays;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Rulesets.Taiko.Mods
{
@@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
{
public override Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList mods) => new Score
{
- ScoreInfo = new ScoreInfo { User = new User { Username = "mekkadosu!" } },
+ ScoreInfo = new ScoreInfo { User = new APIUser { Username = "mekkadosu!" } },
Replay = new TaikoAutoGenerator(beatmap).Generate(),
};
}
diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
index 7a95856c36..0bd7c19200 100644
--- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
+++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
@@ -112,7 +112,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.AreEqual("Renatus", metadata.TitleUnicode);
Assert.AreEqual("Soleily", metadata.Artist);
Assert.AreEqual("Soleily", metadata.ArtistUnicode);
- Assert.AreEqual("Gamu", metadata.AuthorString);
+ Assert.AreEqual("Gamu", metadata.Author.Username);
Assert.AreEqual("Insane", beatmapInfo.Version);
Assert.AreEqual(string.Empty, metadata.Source);
Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", metadata.Tags);
@@ -547,7 +547,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.DoesNotThrow(() => beatmap = decoder.Decode(stream));
Assert.IsNotNull(beatmap);
Assert.AreEqual("Beatmap with corrupted header", beatmap.Metadata.Title);
- Assert.AreEqual("Evil Hacker", beatmap.Metadata.AuthorString);
+ Assert.AreEqual("Evil Hacker", beatmap.Metadata.Author.Username);
}
}
@@ -565,7 +565,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.DoesNotThrow(() => beatmap = decoder.Decode(stream));
Assert.IsNotNull(beatmap);
Assert.AreEqual("Beatmap with no header", beatmap.Metadata.Title);
- Assert.AreEqual("Incredibly Evil Hacker", beatmap.Metadata.AuthorString);
+ Assert.AreEqual("Incredibly Evil Hacker", beatmap.Metadata.Author.Username);
}
}
@@ -583,7 +583,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.DoesNotThrow(() => beatmap = decoder.Decode(stream));
Assert.IsNotNull(beatmap);
Assert.AreEqual("Empty lines at start", beatmap.Metadata.Title);
- Assert.AreEqual("Edge Case Hunter", beatmap.Metadata.AuthorString);
+ Assert.AreEqual("Edge Case Hunter", beatmap.Metadata.Author.Username);
}
}
@@ -601,7 +601,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.DoesNotThrow(() => beatmap = decoder.Decode(stream));
Assert.IsNotNull(beatmap);
Assert.AreEqual("The dog ate the file header", beatmap.Metadata.Title);
- Assert.AreEqual("Why does this keep happening", beatmap.Metadata.AuthorString);
+ Assert.AreEqual("Why does this keep happening", beatmap.Metadata.Author.Username);
}
}
@@ -619,7 +619,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.DoesNotThrow(() => beatmap = decoder.Decode(stream));
Assert.IsNotNull(beatmap);
Assert.AreEqual("No empty line delimiting header from contents", beatmap.Metadata.Title);
- Assert.AreEqual("Edge Case Hunter", beatmap.Metadata.AuthorString);
+ Assert.AreEqual("Edge Case Hunter", beatmap.Metadata.Author.Username);
}
}
diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs
index 9ec2f37569..37c1dfc657 100644
--- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs
+++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs
@@ -35,7 +35,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.AreEqual("Soleily", meta.Artist);
Assert.AreEqual("Soleily", meta.ArtistUnicode);
Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile);
- Assert.AreEqual("Gamu", meta.AuthorString);
+ Assert.AreEqual("Gamu", meta.Author.Username);
Assert.AreEqual("machinetop_background.jpg", meta.BackgroundFile);
Assert.AreEqual(164471, meta.PreviewTime);
Assert.AreEqual(string.Empty, meta.Source);
diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
index d68d43c998..a19e977c1a 100644
--- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
+++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
@@ -17,12 +17,12 @@ using osu.Framework.Logging;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.IO;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Scoring;
using osu.Game.Tests.Resources;
using osu.Game.Tests.Scores.IO;
-using osu.Game.Users;
using SharpCompress.Archives;
using SharpCompress.Archives.Zip;
using SharpCompress.Common;
@@ -408,8 +408,8 @@ namespace osu.Game.Tests.Beatmaps.IO
var manager = osu.Dependencies.Get();
// ReSharper disable once AccessToModifiedClosure
- manager.ItemUpdated.BindValueChanged(_ => Interlocked.Increment(ref itemAddRemoveFireCount));
- manager.ItemRemoved.BindValueChanged(_ => Interlocked.Increment(ref itemAddRemoveFireCount));
+ manager.ItemUpdated += _ => Interlocked.Increment(ref itemAddRemoveFireCount);
+ manager.ItemRemoved += _ => Interlocked.Increment(ref itemAddRemoveFireCount);
var imported = await LoadOszIntoOsu(osu);
@@ -859,7 +859,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var manager = osu.Dependencies.Get();
- var working = manager.CreateNew(new OsuRuleset().RulesetInfo, User.SYSTEM_USER);
+ var working = manager.CreateNew(new OsuRuleset().RulesetInfo, APIUser.SYSTEM_USER);
var beatmap = working.Beatmap;
@@ -892,7 +892,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var osu = LoadOsuIntoHost(host);
var manager = osu.Dependencies.Get();
- var working = manager.CreateNew(new OsuRuleset().RulesetInfo, User.SYSTEM_USER);
+ var working = manager.CreateNew(new OsuRuleset().RulesetInfo, APIUser.SYSTEM_USER);
manager.Save(working.BeatmapInfo, working.Beatmap);
@@ -919,7 +919,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var osu = LoadOsuIntoHost(host);
var manager = osu.Dependencies.Get();
- var working = manager.CreateNew(new OsuRuleset().RulesetInfo, User.SYSTEM_USER);
+ var working = manager.CreateNew(new OsuRuleset().RulesetInfo, APIUser.SYSTEM_USER);
((Beatmap)working.Beatmap).HitObjects.Add(new HitCircle { StartTime = 5000 });
diff --git a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs
index d11da5e2a3..eaf5d107ca 100644
--- a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs
+++ b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs
@@ -60,7 +60,7 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.AreEqual("Soleily", meta.Artist);
Assert.AreEqual("Soleily", meta.ArtistUnicode);
Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile);
- Assert.AreEqual("Deif", meta.AuthorString);
+ Assert.AreEqual("Deif", meta.Author.Username);
Assert.AreEqual("machinetop_background.jpg", meta.BackgroundFile);
Assert.AreEqual(164471, meta.PreviewTime);
Assert.AreEqual(string.Empty, meta.Source);
diff --git a/osu.Game.Tests/Beatmaps/ToStringFormattingTest.cs b/osu.Game.Tests/Beatmaps/ToStringFormattingTest.cs
index c477bbd9cf..da7f32a2d3 100644
--- a/osu.Game.Tests/Beatmaps/ToStringFormattingTest.cs
+++ b/osu.Game.Tests/Beatmaps/ToStringFormattingTest.cs
@@ -3,7 +3,7 @@
using NUnit.Framework;
using osu.Game.Beatmaps;
-using osu.Game.Users;
+using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Tests.Beatmaps
{
@@ -34,7 +34,7 @@ namespace osu.Game.Tests.Beatmaps
{
Artist = "artist",
Title = "title",
- Author = new User { Username = "creator" }
+ Author = new APIUser { Username = "creator" }
}
};
@@ -50,7 +50,7 @@ namespace osu.Game.Tests.Beatmaps
{
Artist = "artist",
Title = "title",
- Author = new User { Username = "creator" }
+ Author = new APIUser { Username = "creator" }
},
Version = "difficulty"
};
diff --git a/osu.Game.Tests/Chat/TestSceneChannelManager.cs b/osu.Game.Tests/Chat/TestSceneChannelManager.cs
index 5e22101e5c..eaacc623c9 100644
--- a/osu.Game.Tests/Chat/TestSceneChannelManager.cs
+++ b/osu.Game.Tests/Chat/TestSceneChannelManager.cs
@@ -9,9 +9,9 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Chat;
using osu.Game.Tests.Visual;
-using osu.Game.Users;
namespace osu.Game.Tests.Chat
{
@@ -133,7 +133,7 @@ namespace osu.Game.Tests.Chat
}
}
- private Channel createChannel(int id, ChannelType type) => new Channel(new User())
+ private Channel createChannel(int id, ChannelType type) => new Channel(new APIUser())
{
Id = id,
Name = $"Channel {id}",
diff --git a/osu.Game.Tests/Database/BeatmapImporterTests.cs b/osu.Game.Tests/Database/BeatmapImporterTests.cs
index a21f935f6b..e1fe1e224e 100644
--- a/osu.Game.Tests/Database/BeatmapImporterTests.cs
+++ b/osu.Game.Tests/Database/BeatmapImporterTests.cs
@@ -482,7 +482,10 @@ namespace osu.Game.Tests.Database
var metadata = new RealmBeatmapMetadata
{
Artist = "SomeArtist",
- Author = "SomeAuthor"
+ Author =
+ {
+ Username = "SomeAuthor"
+ }
};
var ruleset = realmFactory.Context.All().First();
diff --git a/osu.Game.Tests/Database/TestRealmKeyBindingStore.cs b/osu.Game.Tests/Database/TestRealmKeyBindingStore.cs
index f10b11733e..860828ae81 100644
--- a/osu.Game.Tests/Database/TestRealmKeyBindingStore.cs
+++ b/osu.Game.Tests/Database/TestRealmKeyBindingStore.cs
@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using NUnit.Framework;
+using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Framework.Platform;
using osu.Game.Database;
@@ -33,7 +34,7 @@ namespace osu.Game.Tests.Database
storage = new NativeStorage(directory.FullName);
realmContextFactory = new RealmContextFactory(storage, "test");
- keyBindingStore = new RealmKeyBindingStore(realmContextFactory);
+ keyBindingStore = new RealmKeyBindingStore(realmContextFactory, new ReadableKeyCombinationProvider());
}
[Test]
diff --git a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs
index 2918dde2db..05bfae7e63 100644
--- a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs
@@ -54,7 +54,7 @@ namespace osu.Game.Tests.Editing.Checks
{
// While this is a problem, it is out of scope for this check and is caught by a different one.
beatmap.Metadata.BackgroundFile = string.Empty;
- var context = getContext(null, System.Array.Empty());
+ var context = getContext(null, new MemoryStream(System.Array.Empty()));
Assert.That(check.Run(context), Is.Empty);
}
@@ -103,7 +103,7 @@ namespace osu.Game.Tests.Editing.Checks
[Test]
public void TestTooUncompressed()
{
- var context = getContext(new Texture(1920, 1080), new byte[1024 * 1024 * 3]);
+ var context = getContext(new Texture(1920, 1080), new MemoryStream(new byte[1024 * 1024 * 3]));
var issues = check.Run(context).ToList();
@@ -111,19 +111,32 @@ namespace osu.Game.Tests.Editing.Checks
Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateTooUncompressed);
}
- private BeatmapVerifierContext getContext(Texture background, [CanBeNull] byte[] fileBytes = null)
+ [Test]
+ public void TestStreamClosed()
{
- return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(background, fileBytes).Object);
+ var background = new Texture(1920, 1080);
+ var stream = new Mock(new byte[1024 * 1024]);
+
+ var context = getContext(background, stream.Object);
+
+ Assert.That(check.Run(context), Is.Empty);
+
+ stream.Verify(x => x.Close(), Times.Once());
+ }
+
+ private BeatmapVerifierContext getContext(Texture background, [CanBeNull] Stream stream = null)
+ {
+ return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(background, stream).Object);
}
///
- /// Returns the mock of the working beatmap with the given background and filesize.
+ /// Returns the mock of the working beatmap with the given background and its file stream.
///
/// The texture of the background.
- /// The bytes that represent the background file.
- private Mock getMockWorkingBeatmap(Texture background, [CanBeNull] byte[] fileBytes = null)
+ /// The stream representing the background file.
+ private Mock getMockWorkingBeatmap(Texture background, [CanBeNull] Stream stream = null)
{
- var stream = new MemoryStream(fileBytes ?? new byte[1024 * 1024]);
+ stream ??= new MemoryStream(new byte[1024 * 1024]);
var mock = new Mock();
mock.SetupGet(w => w.Beatmap).Returns(beatmap);
diff --git a/osu.Game.Tests/NonVisual/Multiplayer/StatefulMultiplayerClientTest.cs b/osu.Game.Tests/NonVisual/Multiplayer/StatefulMultiplayerClientTest.cs
index 8e2259bce8..abe5664737 100644
--- a/osu.Game.Tests/NonVisual/Multiplayer/StatefulMultiplayerClientTest.cs
+++ b/osu.Game.Tests/NonVisual/Multiplayer/StatefulMultiplayerClientTest.cs
@@ -6,10 +6,10 @@ using Humanizer;
using NUnit.Framework;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Testing;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Tests.Visual.Multiplayer;
-using osu.Game.Users;
namespace osu.Game.Tests.NonVisual.Multiplayer
{
@@ -21,7 +21,7 @@ namespace osu.Game.Tests.NonVisual.Multiplayer
{
int id = 2000;
- AddRepeatStep("add some users", () => Client.AddUser(new User { Id = id++ }), 5);
+ AddRepeatStep("add some users", () => Client.AddUser(new APIUser { Id = id++ }), 5);
checkPlayingUserCount(0);
AddAssert("playlist item is available", () => Client.CurrentMatchPlayingItem.Value != null);
@@ -64,7 +64,7 @@ namespace osu.Game.Tests.NonVisual.Multiplayer
room.State = MultiplayerRoomState.Playing;
room.Users.Add(new MultiplayerRoomUser(PLAYER_1_ID)
{
- User = new User { Id = PLAYER_1_ID },
+ User = new APIUser { Id = PLAYER_1_ID },
State = MultiplayerUserState.Playing
});
};
diff --git a/osu.Game.Tests/OnlinePlay/StatefulMultiplayerClientTest.cs b/osu.Game.Tests/OnlinePlay/StatefulMultiplayerClientTest.cs
index 82ce588c6f..5a621ecf84 100644
--- a/osu.Game.Tests/OnlinePlay/StatefulMultiplayerClientTest.cs
+++ b/osu.Game.Tests/OnlinePlay/StatefulMultiplayerClientTest.cs
@@ -3,8 +3,8 @@
using NUnit.Framework;
using osu.Framework.Testing;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Tests.Visual.Multiplayer;
-using osu.Game.Users;
namespace osu.Game.Tests.OnlinePlay
{
@@ -14,7 +14,7 @@ namespace osu.Game.Tests.OnlinePlay
[Test]
public void TestUserAddedOnJoin()
{
- var user = new User { Id = 33 };
+ var user = new APIUser { Id = 33 };
AddRepeatStep("add user multiple times", () => Client.AddUser(user), 3);
AddAssert("room has 2 users", () => Client.Room?.Users.Count == 2);
@@ -23,7 +23,7 @@ namespace osu.Game.Tests.OnlinePlay
[Test]
public void TestUserRemovedOnLeave()
{
- var user = new User { Id = 44 };
+ var user = new APIUser { Id = 44 };
AddStep("add user", () => Client.AddUser(user));
AddAssert("room has 2 users", () => Client.Room?.Users.Count == 2);
diff --git a/osu.Game.Tests/Scores/IO/ImportScoreTest.cs b/osu.Game.Tests/Scores/IO/ImportScoreTest.cs
index 2cd02329b7..be7803734e 100644
--- a/osu.Game.Tests/Scores/IO/ImportScoreTest.cs
+++ b/osu.Game.Tests/Scores/IO/ImportScoreTest.cs
@@ -11,12 +11,12 @@ using osu.Framework.Allocation;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.IO.Archives;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Tests.Scores.IO
{
@@ -38,7 +38,7 @@ namespace osu.Game.Tests.Scores.IO
Accuracy = 0.8,
MaxCombo = 500,
Combo = 250,
- User = new User { Username = "Test user" },
+ User = new APIUser { Username = "Test user" },
Date = DateTimeOffset.Now,
OnlineScoreID = 12345,
};
diff --git a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs
index f7d42a2ee6..ec16578b71 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs
@@ -10,10 +10,10 @@ using osu.Framework.Testing;
using osu.Game.Configuration;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Online.API;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Screens;
using osu.Game.Screens.Backgrounds;
using osu.Game.Skinning;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Background
{
@@ -113,7 +113,7 @@ namespace osu.Game.Tests.Visual.Background
AddStep($"set background mode to {source}", () => config.SetValue(OsuSetting.MenuBackgroundSource, source));
private void setSupporter(bool isSupporter) =>
- AddStep($"set supporter {isSupporter}", () => ((DummyAPIAccess)API).LocalUser.Value = new User
+ AddStep($"set supporter {isSupporter}", () => ((DummyAPIAccess)API).LocalUser.Value = new APIUser
{
IsSupporter = isSupporter,
Id = API.LocalUser.Value.Id + 1,
diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
index 693c66ccb0..69ea1dc520 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
@@ -18,6 +18,7 @@ using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Scoring;
@@ -29,7 +30,6 @@ using osu.Game.Screens.Ranking;
using osu.Game.Screens.Select;
using osu.Game.Tests.Beatmaps;
using osu.Game.Tests.Resources;
-using osu.Game.Users;
using osuTK;
using osuTK.Graphics;
@@ -231,7 +231,7 @@ namespace osu.Game.Tests.Visual.Background
AddStep("Transition to Results", () => player.Push(results = new FadeAccessibleResults(new ScoreInfo
{
- User = new User { Username = "osu!" },
+ User = new APIUser { Username = "osu!" },
BeatmapInfo = new TestBeatmap(Ruleset.Value).BeatmapInfo,
Ruleset = Ruleset.Value,
})));
diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs
index 2aeb4ab4e2..0feaa8f480 100644
--- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs
+++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs
@@ -9,17 +9,22 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
+using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables.Cards;
+using osu.Game.Online.API;
+using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
-using osu.Game.Users;
using osuTK;
+using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Tests.Visual.Beatmaps
{
public class TestSceneBeatmapCard : OsuTestScene
{
+ private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
+
private APIBeatmapSet[] testCases;
#region Test case generation
@@ -31,22 +36,51 @@ namespace osu.Game.Tests.Visual.Beatmaps
normal.HasVideo = true;
normal.HasStoryboard = true;
+ var withStatistics = CreateAPIBeatmapSet(Ruleset.Value);
+ withStatistics.Title = withStatistics.TitleUnicode = "play favourite stats";
+ withStatistics.Status = BeatmapSetOnlineStatus.Approved;
+ withStatistics.FavouriteCount = 284_239;
+ withStatistics.PlayCount = 999_001;
+ withStatistics.Ranked = DateTimeOffset.Now.AddDays(-45);
+ withStatistics.HypeStatus = new BeatmapSetHypeStatus
+ {
+ Current = 34,
+ Required = 5
+ };
+ withStatistics.NominationStatus = new BeatmapSetNominationStatus
+ {
+ Current = 1,
+ Required = 2
+ };
+
var undownloadable = getUndownloadableBeatmapSet();
+ undownloadable.LastUpdated = DateTimeOffset.Now.AddYears(-1);
var someDifficulties = getManyDifficultiesBeatmapSet(11);
+ someDifficulties.Title = someDifficulties.TitleUnicode = "favourited";
someDifficulties.Title = someDifficulties.TitleUnicode = "some difficulties";
someDifficulties.Status = BeatmapSetOnlineStatus.Qualified;
+ someDifficulties.HasFavourited = true;
+ someDifficulties.FavouriteCount = 1;
+ someDifficulties.NominationStatus = new BeatmapSetNominationStatus
+ {
+ Current = 2,
+ Required = 2
+ };
var manyDifficulties = getManyDifficultiesBeatmapSet(100);
manyDifficulties.Status = BeatmapSetOnlineStatus.Pending;
var explicitMap = CreateAPIBeatmapSet(Ruleset.Value);
+ explicitMap.Title = someDifficulties.TitleUnicode = "explicit beatmap";
explicitMap.HasExplicitContent = true;
var featuredMap = CreateAPIBeatmapSet(Ruleset.Value);
+ featuredMap.Title = someDifficulties.TitleUnicode = "featured artist beatmap";
featuredMap.TrackId = 1;
var explicitFeaturedMap = CreateAPIBeatmapSet(Ruleset.Value);
+ explicitFeaturedMap.Title = someDifficulties.TitleUnicode = "explicit featured artist";
explicitFeaturedMap.HasExplicitContent = true;
explicitFeaturedMap.TrackId = 2;
@@ -59,6 +93,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
testCases = new[]
{
normal,
+ withStatistics,
undownloadable,
someDifficulties,
manyDifficulties,
@@ -75,7 +110,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
Title = "undownloadable beatmap",
Artist = "test",
Source = "more tests",
- Author = new User
+ Author = new APIUser
{
Username = "BanchoBot",
Id = 3,
@@ -120,7 +155,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
OnlineID = 1,
Title = "many difficulties beatmap",
Artist = "test",
- Author = new User
+ Author = new APIUser
{
Username = "BanchoBot",
Id = 3,
@@ -134,6 +169,19 @@ namespace osu.Game.Tests.Visual.Beatmaps
#endregion
+ [SetUpSteps]
+ public void SetUpSteps()
+ {
+ AddStep("register request handling", () => dummyAPI.HandleRequest = request =>
+ {
+ if (!(request is PostBeatmapFavouriteRequest))
+ return false;
+
+ request.TriggerSuccess();
+ return true;
+ });
+ }
+
private Drawable createContent(OverlayColourScheme colourScheme, Func creationFunc)
{
var colourProvider = new OverlayColourProvider(colourScheme);
diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs
new file mode 100644
index 0000000000..77c9debef6
--- /dev/null
+++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs
@@ -0,0 +1,86 @@
+// Copyright (c) ppy Pty Ltd . 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.Sprites;
+using osu.Framework.Testing;
+using osu.Game.Beatmaps.Drawables.Cards.Buttons;
+using osu.Game.Online.API;
+using osu.Game.Online.API.Requests;
+using osu.Game.Online.API.Requests.Responses;
+using osu.Game.Overlays;
+using osu.Game.Resources.Localisation.Web;
+using osuTK;
+using osuTK.Input;
+
+namespace osu.Game.Tests.Visual.Beatmaps
+{
+ public class TestSceneBeatmapCardFavouriteButton : OsuManualInputManagerTestScene
+ {
+ private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
+
+ [Cached]
+ private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
+
+ [Test]
+ public void TestInitialState([Values] bool favourited)
+ {
+ APIBeatmapSet beatmapSetInfo = null;
+ FavouriteButton button = null;
+
+ AddStep("create beatmap set", () =>
+ {
+ beatmapSetInfo = CreateAPIBeatmapSet(Ruleset.Value);
+ beatmapSetInfo.HasFavourited = favourited;
+ });
+ AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo) { Scale = new Vector2(2) });
+
+ assertCorrectIcon(favourited);
+ AddAssert("correct tooltip text", () => button.TooltipText == (favourited ? BeatmapsetsStrings.ShowDetailsUnfavourite : BeatmapsetsStrings.ShowDetailsFavourite));
+ }
+
+ [Test]
+ public void TestRequestHandling()
+ {
+ APIBeatmapSet beatmapSetInfo = null;
+ FavouriteButton button = null;
+ BeatmapFavouriteAction? lastRequestAction = null;
+
+ AddStep("create beatmap set", () => beatmapSetInfo = CreateAPIBeatmapSet(Ruleset.Value));
+ AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo) { Scale = new Vector2(2) });
+
+ assertCorrectIcon(false);
+
+ AddStep("register request handling", () => dummyAPI.HandleRequest = request =>
+ {
+ if (!(request is PostBeatmapFavouriteRequest favouriteRequest))
+ return false;
+
+ lastRequestAction = favouriteRequest.Action;
+ request.TriggerSuccess();
+ return true;
+ });
+
+ AddStep("click icon", () =>
+ {
+ InputManager.MoveMouseTo(button);
+ InputManager.Click(MouseButton.Left);
+ });
+ AddUntilStep("favourite request sent", () => lastRequestAction == BeatmapFavouriteAction.Favourite);
+ assertCorrectIcon(true);
+
+ AddStep("click icon", () =>
+ {
+ InputManager.MoveMouseTo(button);
+ InputManager.Click(MouseButton.Left);
+ });
+ AddUntilStep("unfavourite request sent", () => lastRequestAction == BeatmapFavouriteAction.UnFavourite);
+ assertCorrectIcon(false);
+ }
+
+ private void assertCorrectIcon(bool favourited) => AddAssert("icon correct",
+ () => this.ChildrenOfType().Single().Icon.Equals(favourited ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart));
+ }
+}
diff --git a/osu.Game.Tests/Visual/Components/TestScenePreviewTrackManager.cs b/osu.Game.Tests/Visual/Components/TestScenePreviewTrackManager.cs
index 89e20043fb..82b6710a17 100644
--- a/osu.Game.Tests/Visual/Components/TestScenePreviewTrackManager.cs
+++ b/osu.Game.Tests/Visual/Components/TestScenePreviewTrackManager.cs
@@ -13,10 +13,17 @@ namespace osu.Game.Tests.Visual.Components
{
public class TestScenePreviewTrackManager : OsuTestScene, IPreviewTrackOwner
{
- private readonly TestPreviewTrackManager trackManager = new TestPreviewTrackManager();
+ private readonly IAdjustableAudioComponent gameTrackAudio = new AudioAdjustments();
+
+ private readonly TestPreviewTrackManager trackManager;
private AudioManager audio;
+ public TestScenePreviewTrackManager()
+ {
+ trackManager = new TestPreviewTrackManager(gameTrackAudio);
+ }
+
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
@@ -151,19 +158,19 @@ namespace osu.Game.Tests.Visual.Components
audio.VolumeTrack.Value = 1;
});
- AddAssert("game not muted", () => audio.Tracks.AggregateVolume.Value != 0);
+ AddAssert("game not muted", () => gameTrackAudio.AggregateVolume.Value != 0);
AddStep("get track", () => Add(owner = new TestTrackOwner(track = getTrack())));
AddUntilStep("wait loaded", () => track.IsLoaded);
AddStep("start track", () => track.Start());
- AddAssert("game is muted", () => audio.Tracks.AggregateVolume.Value == 0);
+ AddAssert("game is muted", () => gameTrackAudio.AggregateVolume.Value == 0);
if (stopAnyPlaying)
AddStep("stop any playing", () => trackManager.StopAnyPlaying(owner));
else
AddStep("stop track", () => track.Stop());
- AddAssert("game not muted", () => audio.Tracks.AggregateVolume.Value != 0);
+ AddAssert("game not muted", () => gameTrackAudio.AggregateVolume.Value != 0);
}
[Test]
@@ -224,6 +231,11 @@ namespace osu.Game.Tests.Visual.Components
public new PreviewTrack CurrentTrack => base.CurrentTrack;
+ public TestPreviewTrackManager(IAdjustableAudioComponent mainTrackAdjustments)
+ : base(mainTrackAdjustments)
+ {
+ }
+
protected override TrackManagerPreviewTrack CreatePreviewTrack(IBeatmapSetInfo beatmapSetInfo, ITrackStore trackStore) => new TestPreviewTrack(beatmapSetInfo, trackStore);
public override bool UpdateSubTree()
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs
index 0441c5641e..74212de210 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs
@@ -7,8 +7,8 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Framework.Utils;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Screens.Play.HUD;
-using osu.Game.Users;
using osuTK;
namespace osu.Game.Tests.Visual.Gameplay
@@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.Gameplay
playerScore.Value = 1222333;
});
- AddStep("add local player", () => createLeaderboardScore(playerScore, new User { Username = "You", Id = 3 }, true));
+ AddStep("add local player", () => createLeaderboardScore(playerScore, new APIUser { Username = "You", Id = 3 }, true));
AddStep("toggle expanded", () => leaderboard.Expanded.Value = !leaderboard.Expanded.Value);
AddSliderStep("set player score", 50, 5000000, 1222333, v => playerScore.Value = v);
}
@@ -50,8 +50,8 @@ namespace osu.Game.Tests.Visual.Gameplay
var player2Score = new BindableDouble(1234567);
var player3Score = new BindableDouble(1111111);
- AddStep("add player 2", () => createLeaderboardScore(player2Score, new User { Username = "Player 2" }));
- AddStep("add player 3", () => createLeaderboardScore(player3Score, new User { Username = "Player 3" }));
+ AddStep("add player 2", () => createLeaderboardScore(player2Score, new APIUser { Username = "Player 2" }));
+ AddStep("add player 3", () => createLeaderboardScore(player3Score, new APIUser { Username = "Player 3" }));
AddUntilStep("is player 2 position #1", () => leaderboard.CheckPositionByUsername("Player 2", 1));
AddUntilStep("is player position #2", () => leaderboard.CheckPositionByUsername("You", 2));
@@ -72,38 +72,38 @@ namespace osu.Game.Tests.Visual.Gameplay
public void TestRandomScores()
{
int playerNumber = 1;
- AddRepeatStep("add player with random score", () => createRandomScore(new User { Username = $"Player {playerNumber++}" }), 10);
+ AddRepeatStep("add player with random score", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 10);
}
[Test]
public void TestExistingUsers()
{
- AddStep("add peppy", () => createRandomScore(new User { Username = "peppy", Id = 2 }));
- AddStep("add smoogipoo", () => createRandomScore(new User { Username = "smoogipoo", Id = 1040328 }));
- AddStep("add flyte", () => createRandomScore(new User { Username = "flyte", Id = 3103765 }));
- AddStep("add frenzibyte", () => createRandomScore(new User { Username = "frenzibyte", Id = 14210502 }));
+ AddStep("add peppy", () => createRandomScore(new APIUser { Username = "peppy", Id = 2 }));
+ AddStep("add smoogipoo", () => createRandomScore(new APIUser { Username = "smoogipoo", Id = 1040328 }));
+ AddStep("add flyte", () => createRandomScore(new APIUser { Username = "flyte", Id = 3103765 }));
+ AddStep("add frenzibyte", () => createRandomScore(new APIUser { Username = "frenzibyte", Id = 14210502 }));
}
[Test]
public void TestMaxHeight()
{
int playerNumber = 1;
- AddRepeatStep("add 3 other players", () => createRandomScore(new User { Username = $"Player {playerNumber++}" }), 3);
+ AddRepeatStep("add 3 other players", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 3);
checkHeight(4);
- AddRepeatStep("add 4 other players", () => createRandomScore(new User { Username = $"Player {playerNumber++}" }), 4);
+ AddRepeatStep("add 4 other players", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 4);
checkHeight(8);
- AddRepeatStep("add 4 other players", () => createRandomScore(new User { Username = $"Player {playerNumber++}" }), 4);
+ AddRepeatStep("add 4 other players", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 4);
checkHeight(8);
void checkHeight(int panelCount)
=> AddAssert($"leaderboard height is {panelCount} panels high", () => leaderboard.DrawHeight == (GameplayLeaderboardScore.PANEL_HEIGHT + leaderboard.Spacing) * panelCount);
}
- private void createRandomScore(User user) => createLeaderboardScore(new BindableDouble(RNG.Next(0, 5_000_000)), user);
+ private void createRandomScore(APIUser user) => createLeaderboardScore(new BindableDouble(RNG.Next(0, 5_000_000)), user);
- private void createLeaderboardScore(BindableDouble score, User user, bool isTracked = false)
+ private void createLeaderboardScore(BindableDouble score, APIUser user, bool isTracked = false)
{
var leaderboardScore = leaderboard.Add(user, isTracked);
leaderboardScore.TotalScore.BindTo(score);
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs
index 64d9addc77..d4036fefc0 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs
@@ -7,15 +7,16 @@ using osu.Framework.Graphics;
using osu.Game.Online;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Scoring;
-using osu.Game.Users;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Testing;
+using osu.Game.Database;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu;
using osu.Game.Screens.Ranking;
using osuTK.Input;
+using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Tests.Visual.Gameplay
{
@@ -113,6 +114,36 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert("button is not enabled", () => !downloadButton.ChildrenOfType().First().Enabled.Value);
}
+ [Resolved]
+ private ScoreManager scoreManager { get; set; }
+
+ [Test]
+ public void TestScoreImportThenDelete()
+ {
+ ILive imported = null;
+
+ AddStep("create button without replay", () =>
+ {
+ Child = downloadButton = new TestReplayDownloadButton(getScoreInfo(false))
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ };
+ });
+
+ AddUntilStep("wait for load", () => downloadButton.IsLoaded);
+
+ AddUntilStep("state is not downloaded", () => downloadButton.State.Value == DownloadState.NotDownloaded);
+
+ AddStep("import score", () => imported = scoreManager.Import(getScoreInfo(true)).Result);
+
+ AddUntilStep("state is available", () => downloadButton.State.Value == DownloadState.LocallyAvailable);
+
+ AddStep("delete score", () => scoreManager.Delete(imported.Value));
+
+ AddUntilStep("state is not downloaded", () => downloadButton.State.Value == DownloadState.NotDownloaded);
+ }
+
[Test]
public void CreateButtonWithNoScore()
{
@@ -139,7 +170,7 @@ namespace osu.Game.Tests.Visual.Gameplay
RulesetID = 0,
Beatmap = CreateAPIBeatmapSet(new OsuRuleset().RulesetInfo).Beatmaps.First(),
HasReplay = replayAvailable,
- User = new User
+ User = new APIUser
{
Id = 39828,
Username = @"WubWoofWolf",
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs
index 21c5d89aca..20e859dd2b 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs
@@ -9,6 +9,7 @@ using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Database;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Spectator;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Replays;
@@ -18,13 +19,12 @@ using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps.IO;
using osu.Game.Tests.Visual.Multiplayer;
using osu.Game.Tests.Visual.Spectator;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestSceneSpectator : ScreenTestScene
{
- private readonly User streamingUser = new User { Id = MultiplayerTestScene.PLAYER_1_ID, Username = "Test user" };
+ private readonly APIUser streamingUser = new APIUser { Id = MultiplayerTestScene.PLAYER_1_ID, Username = "Test user" };
[Cached(typeof(UserLookupCache))]
private UserLookupCache lookupCache = new TestUserLookupCache();
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs
index 89fea1f92d..2a82c65c7c 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs
@@ -4,11 +4,11 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Game.Online.API;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Spectator;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mania;
using osu.Game.Tests.Visual.Spectator;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Gameplay
{
@@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual.Gameplay
public override void SetUpSteps()
{
- AddStep("set dummy user", () => dummyAPIAccess.LocalUser.Value = new User
+ AddStep("set dummy user", () => dummyAPIAccess.LocalUser.Value = new APIUser
{
Id = dummy_user_id,
Username = "DummyUser"
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneUnstableRateCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneUnstableRateCounter.cs
new file mode 100644
index 0000000000..0dc25cf378
--- /dev/null
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneUnstableRateCounter.cs
@@ -0,0 +1,98 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Testing;
+using osu.Game.Rulesets.Judgements;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Rulesets.Osu.Scoring;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Screens.Play.HUD;
+using osuTK;
+
+namespace osu.Game.Tests.Visual.Gameplay
+{
+ public class TestSceneUnstableRateCounter : OsuTestScene
+ {
+ [Cached(typeof(ScoreProcessor))]
+ private TestScoreProcessor scoreProcessor = new TestScoreProcessor();
+
+ private readonly OsuHitWindows hitWindows = new OsuHitWindows();
+
+ private UnstableRateCounter counter;
+
+ private double prev;
+
+ [SetUpSteps]
+ public void SetUp()
+ {
+ AddStep("Reset Score Processor", () => scoreProcessor.Reset());
+ }
+
+ [Test]
+ public void TestBasic()
+ {
+ AddStep("Create Display", recreateDisplay);
+
+ // Needs multiples 2 by the nature of UR, and went for 4 to be safe.
+ // Creates a 250 UR by placing a +25ms then a -25ms judgement, which then results in a 250 UR
+ AddRepeatStep("Set UR to 250", () => applyJudgement(25, true), 4);
+
+ AddUntilStep("UR = 250", () => counter.Current.Value == 250.0);
+
+ AddRepeatStep("Revert UR", () =>
+ {
+ scoreProcessor.RevertResult(
+ new JudgementResult(new HitCircle { HitWindows = hitWindows }, new Judgement())
+ {
+ TimeOffset = 25,
+ Type = HitResult.Perfect,
+ });
+ }, 4);
+
+ AddUntilStep("UR is 0", () => counter.Current.Value == 0.0);
+ AddUntilStep("Counter is invalid", () => counter.Child.Alpha == 0.3f);
+
+ //Sets a UR of 0 by creating 10 10ms offset judgements. Since average = offset, UR = 0
+ AddRepeatStep("Set UR to 0", () => applyJudgement(10, false), 10);
+ //Applies a UR of 100 by creating 10 -10ms offset judgements. At the 10th judgement, offset should be 100.
+ AddRepeatStep("Bring UR to 100", () => applyJudgement(-10, false), 10);
+ }
+
+ private void recreateDisplay()
+ {
+ Clear();
+
+ Add(counter = new UnstableRateCounter
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Scale = new Vector2(5),
+ });
+ }
+
+ private void applyJudgement(double offsetMs, bool alt)
+ {
+ double placement = offsetMs;
+
+ if (alt)
+ {
+ placement = prev > 0 ? -offsetMs : offsetMs;
+ prev = placement;
+ }
+
+ scoreProcessor.ApplyResult(new JudgementResult(new HitCircle { HitWindows = hitWindows }, new Judgement())
+ {
+ TimeOffset = placement,
+ Type = HitResult.Perfect,
+ });
+ }
+
+ private class TestScoreProcessor : ScoreProcessor
+ {
+ public void Reset() => base.Reset(false);
+ }
+ }
+}
diff --git a/osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs b/osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs
index 9cbdee3632..db5891bd4e 100644
--- a/osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs
+++ b/osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs
@@ -3,8 +3,8 @@
using osu.Framework.Allocation;
using osu.Game.Online.API;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Screens.Menu;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Menus
{
@@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual.Menus
AddStep("toggle support", () =>
{
- ((DummyAPIAccess)API).LocalUser.Value = new User
+ ((DummyAPIAccess)API).LocalUser.Value = new APIUser
{
Username = API.LocalUser.Value.Username,
Id = API.LocalUser.Value.Id + 1,
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs
index 84a6e95883..721862c177 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs
@@ -10,6 +10,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Framework.Utils;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osu.Game.Online.Rooms.RoomStatuses;
using osu.Game.Overlays;
@@ -17,7 +18,6 @@ using osu.Game.Rulesets.Osu;
using osu.Game.Screens.OnlinePlay.Lounge;
using osu.Game.Screens.OnlinePlay.Lounge.Components;
using osu.Game.Tests.Beatmaps;
-using osu.Game.Users;
using osuTK;
namespace osu.Game.Tests.Visual.Multiplayer
@@ -174,11 +174,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
private DrawableRoom createLoungeRoom(Room room)
{
- room.Host.Value ??= new User { Username = "peppy", Id = 2 };
+ room.Host.Value ??= new APIUser { Username = "peppy", Id = 2 };
if (room.RecentParticipants.Count == 0)
{
- room.RecentParticipants.AddRange(Enumerable.Range(0, 20).Select(i => new User
+ room.RecentParticipants.AddRange(Enumerable.Range(0, 20).Select(i => new APIUser
{
Id = i,
Username = $"User {i}"
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomParticipantsList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomParticipantsList.cs
index 982dfc5cd9..60f47a01a9 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomParticipantsList.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomParticipantsList.cs
@@ -5,10 +5,10 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Testing;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osu.Game.Screens.OnlinePlay.Lounge.Components;
using osu.Game.Tests.Visual.OnlinePlay;
-using osu.Game.Users;
using osu.Game.Users.Drawables;
namespace osu.Game.Tests.Visual.Multiplayer
@@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
Name = { Value = "test room" },
Host =
{
- Value = new User
+ Value = new APIUser
{
Id = 2,
Username = "peppy",
@@ -137,7 +137,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void addUser(int id)
{
- SelectedRoom.Value.RecentParticipants.Add(new User
+ SelectedRoom.Value.RecentParticipants.Add(new APIUser
{
Id = id,
Username = $"User {id}"
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs
index afd48d5191..8ac0a2cbe5 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs
@@ -14,6 +14,7 @@ using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics.Containers;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osu.Game.Overlays.BeatmapListing.Panels;
using osu.Game.Rulesets;
@@ -21,7 +22,6 @@ using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.OnlinePlay;
using osu.Game.Tests.Beatmaps;
-using osu.Game.Users;
using osuTK;
using osuTK.Input;
@@ -294,7 +294,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
Metadata = new BeatmapMetadata
{
Artist = "Artist",
- Author = new User { Username = "Creator name here" },
+ Author = new APIUser { Username = "Creator name here" },
Title = "Long title used to check background colour",
},
BeatmapSet = new BeatmapSetInfo()
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchLeaderboard.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchLeaderboard.cs
index a7a5f3af39..955710bd50 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchLeaderboard.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchLeaderboard.cs
@@ -10,8 +10,8 @@ using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osu.Game.Screens.OnlinePlay.Match.Components;
using osu.Game.Tests.Visual.OnlinePlay;
-using osu.Game.Users;
using osuTK;
+using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Tests.Visual.Multiplayer
{
@@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
new APIUserScoreAggregate
{
UserID = 2,
- User = new User { Id = 2, Username = "peppy" },
+ User = new APIUser { Id = 2, Username = "peppy" },
TotalScore = 995533,
RoomID = 3,
CompletedBeatmaps = 1,
@@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
new APIUserScoreAggregate
{
UserID = 1040328,
- User = new User { Id = 1040328, Username = "smoogipoo" },
+ User = new APIUser { Id = 1040328, Username = "smoogipoo" },
TotalScore = 981100,
RoomID = 3,
CompletedBeatmaps = 1,
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorLeaderboard.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorLeaderboard.cs
index bd5320354e..a61e505970 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorLeaderboard.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorLeaderboard.cs
@@ -6,11 +6,11 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Testing;
using osu.Framework.Timing;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Rulesets.Osu.Scoring;
using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate;
using osu.Game.Screens.Play.HUD;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Multiplayer
{
@@ -35,7 +35,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
foreach ((int userId, var _) in clocks)
{
SpectatorClient.StartPlay(userId, 0);
- OnlinePlayDependencies.Client.AddUser(new User { Id = userId });
+ OnlinePlayDependencies.Client.AddUser(new APIUser { Id = userId });
}
});
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs
index 7ff8c82145..fdd01446b9 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs
@@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
using osu.Game.Rulesets.UI;
@@ -19,7 +20,6 @@ using osu.Game.Screens.Play;
using osu.Game.Screens.Play.HUD;
using osu.Game.Screens.Play.PlayerSettings;
using osu.Game.Tests.Beatmaps.IO;
-using osu.Game.Users;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Multiplayer
@@ -59,8 +59,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("start players silently", () =>
{
- OnlinePlayDependencies.Client.AddUser(new User { Id = PLAYER_1_ID }, true);
- OnlinePlayDependencies.Client.AddUser(new User { Id = PLAYER_2_ID }, true);
+ OnlinePlayDependencies.Client.AddUser(new APIUser { Id = PLAYER_1_ID }, true);
+ OnlinePlayDependencies.Client.AddUser(new APIUser { Id = PLAYER_2_ID }, true);
playingUsers.Add(new MultiplayerRoomUser(PLAYER_1_ID));
playingUsers.Add(new MultiplayerRoomUser(PLAYER_2_ID));
@@ -120,13 +120,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("start players", () =>
{
- var player1 = OnlinePlayDependencies.Client.AddUser(new User { Id = PLAYER_1_ID }, true);
+ var player1 = OnlinePlayDependencies.Client.AddUser(new APIUser { Id = PLAYER_1_ID }, true);
player1.MatchState = new TeamVersusUserState
{
TeamID = 0,
};
- var player2 = OnlinePlayDependencies.Client.AddUser(new User { Id = PLAYER_2_ID }, true);
+ var player2 = OnlinePlayDependencies.Client.AddUser(new APIUser { Id = PLAYER_2_ID }, true);
player2.MatchState = new TeamVersusUserState
{
TeamID = 1,
@@ -367,7 +367,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
var user = new MultiplayerRoomUser(id)
{
- User = new User { Id = id },
+ User = new APIUser { Id = id },
};
OnlinePlayDependencies.Client.AddUser(user.User, true);
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs
index 38cf9d662f..e831d5b564 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs
@@ -17,6 +17,7 @@ using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Overlays.Mods;
@@ -32,7 +33,6 @@ using osu.Game.Screens.Play;
using osu.Game.Screens.Ranking;
using osu.Game.Screens.Spectate;
using osu.Game.Tests.Resources;
-using osu.Game.Users;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Multiplayer
@@ -129,12 +129,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void addRandomPlayer()
{
int randomUser = RNG.Next(200000, 500000);
- client.AddUser(new User { Id = randomUser, Username = $"user {randomUser}" });
+ client.AddUser(new APIUser { Id = randomUser, Username = $"user {randomUser}" });
}
private void removeLastUser()
{
- User lastUser = client.Room?.Users.Last().User;
+ APIUser lastUser = client.Room?.Users.Last().User;
if (lastUser == null || lastUser == client.LocalUser?.User)
return;
@@ -144,7 +144,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void kickLastUser()
{
- User lastUser = client.Room?.Users.Last().User;
+ APIUser lastUser = client.Room?.Users.Last().User;
if (lastUser == null || lastUser == client.LocalUser?.User)
return;
@@ -414,7 +414,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("join other user (ready, host)", () =>
{
- client.AddUser(new User { Id = MultiplayerTestScene.PLAYER_1_ID, Username = "Other" });
+ client.AddUser(new APIUser { Id = MultiplayerTestScene.PLAYER_1_ID, Username = "Other" });
client.TransferHost(MultiplayerTestScene.PLAYER_1_ID);
client.ChangeUserState(MultiplayerTestScene.PLAYER_1_ID, MultiplayerUserState.Ready);
});
@@ -454,7 +454,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("join other user (ready, host)", () =>
{
- client.AddUser(new User { Id = MultiplayerTestScene.PLAYER_1_ID, Username = "Other" });
+ client.AddUser(new APIUser { Id = MultiplayerTestScene.PLAYER_1_ID, Username = "Other" });
client.TransferHost(MultiplayerTestScene.PLAYER_1_ID);
client.ChangeUserState(MultiplayerTestScene.PLAYER_1_ID, MultiplayerUserState.Ready);
});
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs
index 832998d5d3..902629765f 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs
@@ -11,6 +11,7 @@ using osu.Framework.Graphics;
using osu.Framework.Utils;
using osu.Game.Configuration;
using osu.Game.Online.API;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Spectator;
using osu.Game.Replays.Legacy;
@@ -20,7 +21,6 @@ using osu.Game.Scoring;
using osu.Game.Screens.Play.HUD;
using osu.Game.Tests.Visual.OnlinePlay;
using osu.Game.Tests.Visual.Spectator;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Multiplayer
{
@@ -58,7 +58,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
foreach (int user in users)
{
SpectatorClient.StartPlay(user, Beatmap.Value.BeatmapInfo.OnlineBeatmapID ?? 0);
- multiplayerUsers.Add(OnlinePlayDependencies.Client.AddUser(new User { Id = user }, true));
+ multiplayerUsers.Add(OnlinePlayDependencies.Client.AddUser(new APIUser { Id = user }, true));
}
Children = new Drawable[]
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboardTeams.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboardTeams.cs
index 3d48ddc7ca..af4e696fce 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboardTeams.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboardTeams.cs
@@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Utils;
using osu.Game.Online.API;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
using osu.Game.Online.Rooms;
@@ -15,7 +16,6 @@ using osu.Game.Screens.OnlinePlay.Multiplayer;
using osu.Game.Screens.Play.HUD;
using osu.Game.Tests.Visual.OnlinePlay;
using osu.Game.Tests.Visual.Spectator;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Multiplayer
{
@@ -62,7 +62,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
foreach (int user in users)
{
SpectatorClient.StartPlay(user, Beatmap.Value.BeatmapInfo.OnlineBeatmapID ?? 0);
- var roomUser = OnlinePlayDependencies.Client.AddUser(new User { Id = user }, true);
+ var roomUser = OnlinePlayDependencies.Client.AddUser(new APIUser { Id = user }, true);
roomUser.MatchState = new TeamVersusUserState
{
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSubScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSubScreen.cs
index 21364fe154..bb5735a3b5 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSubScreen.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSubScreen.cs
@@ -9,6 +9,7 @@ using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Rulesets;
@@ -18,7 +19,6 @@ using osu.Game.Screens.OnlinePlay.Multiplayer;
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
using osu.Game.Tests.Beatmaps;
using osu.Game.Tests.Resources;
-using osu.Game.Users;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Multiplayer
@@ -119,7 +119,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("join other user (ready)", () =>
{
- Client.AddUser(new User { Id = PLAYER_1_ID });
+ Client.AddUser(new APIUser { Id = PLAYER_1_ID });
Client.ChangeUserState(PLAYER_1_ID, MultiplayerUserState.Ready);
});
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs
index 2549681519..671b85164b 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs
@@ -11,6 +11,7 @@ using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Rulesets.Mods;
@@ -34,7 +35,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddAssert("one unique panel", () => this.ChildrenOfType().Select(p => p.User).Distinct().Count() == 1);
- AddStep("add user", () => Client.AddUser(new User
+ AddStep("add user", () => Client.AddUser(new APIUser
{
Id = 3,
Username = "Second",
@@ -63,11 +64,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestRemoveUser()
{
- User secondUser = null;
+ APIUser secondUser = null;
AddStep("add a user", () =>
{
- Client.AddUser(secondUser = new User
+ Client.AddUser(secondUser = new APIUser
{
Id = 3,
Username = "Second",
@@ -146,7 +147,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestCrownChangesStateWhenHostTransferred()
{
- AddStep("add user", () => Client.AddUser(new User
+ AddStep("add user", () => Client.AddUser(new APIUser
{
Id = 3,
Username = "Second",
@@ -165,7 +166,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestKickButtonOnlyPresentWhenHost()
{
- AddStep("add user", () => Client.AddUser(new User
+ AddStep("add user", () => Client.AddUser(new APIUser
{
Id = 3,
Username = "Second",
@@ -186,7 +187,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestKickButtonKicks()
{
- AddStep("add user", () => Client.AddUser(new User
+ AddStep("add user", () => Client.AddUser(new APIUser
{
Id = 3,
Username = "Second",
@@ -205,7 +206,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
for (int i = 0; i < 20; i++)
{
- Client.AddUser(new User
+ Client.AddUser(new APIUser
{
Id = i,
Username = $"User {i}",
@@ -249,7 +250,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("add user", () =>
{
- Client.AddUser(new User
+ Client.AddUser(new APIUser
{
Id = 0,
Username = "User 0",
@@ -295,7 +296,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("add user with mods", () =>
{
- Client.AddUser(new User
+ Client.AddUser(new APIUser
{
Id = 0,
Username = "Baka",
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerReadyButton.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerReadyButton.cs
index 820b403a10..e9612bf55c 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerReadyButton.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerReadyButton.cs
@@ -14,12 +14,12 @@ using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Rulesets;
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
using osu.Game.Tests.Resources;
-using osu.Game.Users;
using osuTK;
using osuTK.Input;
@@ -108,7 +108,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("add second user as host", () =>
{
- Client.AddUser(new User { Id = 2, Username = "Another user" });
+ Client.AddUser(new APIUser { Id = 2, Username = "Another user" });
Client.TransferHost(2);
});
@@ -128,7 +128,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
Client.TransferHost(Client.Room?.Users[0].UserID ?? 0);
if (!allReady)
- Client.AddUser(new User { Id = 2, Username = "Another user" });
+ Client.AddUser(new APIUser { Id = 2, Username = "Another user" });
});
addClickButtonStep();
@@ -142,7 +142,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("add host", () =>
{
- Client.AddUser(new User { Id = 2, Username = "Another user" });
+ Client.AddUser(new APIUser { Id = 2, Username = "Another user" });
Client.TransferHost(2);
});
@@ -158,7 +158,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("setup", () =>
{
Client.TransferHost(Client.Room?.Users[0].UserID ?? 0);
- Client.AddUser(new User { Id = 2, Username = "Another user" });
+ Client.AddUser(new APIUser { Id = 2, Username = "Another user" });
});
addClickButtonStep();
@@ -177,7 +177,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
Client.TransferHost(Client.Room?.Users[0].UserID ?? 0);
for (int i = 0; i < users; i++)
- Client.AddUser(new User { Id = i, Username = "Another user" });
+ Client.AddUser(new APIUser { Id = i, Username = "Another user" });
});
if (!isHost)
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerResults.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerResults.cs
index 5032cdaec7..c0b21c4421 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerResults.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerResults.cs
@@ -3,11 +3,11 @@
using System;
using NUnit.Framework;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osu.Game.Rulesets.Osu;
using osu.Game.Scoring;
using osu.Game.Screens.OnlinePlay.Multiplayer;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Multiplayer
{
@@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
MaxCombo = 500,
Combo = 250,
BeatmapInfo = beatmapInfo,
- User = new User { Username = "Test user" },
+ User = new APIUser { Username = "Test user" },
Date = DateTimeOffset.Now,
OnlineScoreID = 12345,
Ruleset = rulesetInfo,
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectateButton.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectateButton.cs
index 3d08d5da9e..76c8de93c7 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectateButton.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectateButton.cs
@@ -14,12 +14,12 @@ using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Rulesets;
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
using osu.Game.Tests.Resources;
-using osu.Game.Users;
using osuTK;
using osuTK.Input;
@@ -145,7 +145,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestReadyButtonEnabledWhenHostAndUsersReady()
{
- AddStep("add user", () => Client.AddUser(new User { Id = PLAYER_1_ID }));
+ AddStep("add user", () => Client.AddUser(new APIUser { Id = PLAYER_1_ID }));
AddStep("set user ready", () => Client.ChangeUserState(PLAYER_1_ID, MultiplayerUserState.Ready));
addClickSpectateButtonStep();
@@ -157,7 +157,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("add user and transfer host", () =>
{
- Client.AddUser(new User { Id = PLAYER_1_ID });
+ Client.AddUser(new APIUser { Id = PLAYER_1_ID });
Client.TransferHost(PLAYER_1_ID);
});
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerTeamResults.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerTeamResults.cs
index 99d5fd46e9..d391c39c89 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerTeamResults.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerTeamResults.cs
@@ -5,11 +5,11 @@ using System;
using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Bindables;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osu.Game.Rulesets.Osu;
using osu.Game.Scoring;
using osu.Game.Screens.OnlinePlay.Multiplayer;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Multiplayer
{
@@ -35,7 +35,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
MaxCombo = 500,
Combo = 250,
BeatmapInfo = beatmapInfo,
- User = new User { Username = "Test user" },
+ User = new APIUser { Username = "Test user" },
Date = DateTimeOffset.Now,
OnlineScoreID = 12345,
Ruleset = rulesetInfo,
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneRankRangePill.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneRankRangePill.cs
index 9e03743e8d..823ac07cf7 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneRankRangePill.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneRankRangePill.cs
@@ -3,8 +3,8 @@
using NUnit.Framework;
using osu.Framework.Graphics;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Screens.OnlinePlay.Lounge.Components;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Multiplayer
{
@@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("add user", () =>
{
- Client.AddUser(new User
+ Client.AddUser(new APIUser
{
Id = 2,
Statistics = { GlobalRank = 1234 }
@@ -41,19 +41,19 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("add users", () =>
{
- Client.AddUser(new User
+ Client.AddUser(new APIUser
{
Id = 2,
Statistics = { GlobalRank = 1234 }
});
- Client.AddUser(new User
+ Client.AddUser(new APIUser
{
Id = 3,
Statistics = { GlobalRank = 3333 }
});
- Client.AddUser(new User
+ Client.AddUser(new APIUser
{
Id = 4,
Statistics = { GlobalRank = 4321 }
@@ -75,13 +75,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("add users", () =>
{
- Client.AddUser(new User
+ Client.AddUser(new APIUser
{
Id = 2,
Statistics = { GlobalRank = min }
});
- Client.AddUser(new User
+ Client.AddUser(new APIUser
{
Id = 3,
Statistics = { GlobalRank = max }
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneTeamVersus.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneTeamVersus.cs
index ad92886bab..1efa8d6810 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneTeamVersus.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneTeamVersus.cs
@@ -127,9 +127,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddAssert("room type is head to head", () => client.Room?.Settings.MatchType == MatchType.HeadToHead);
+ AddUntilStep("team displays are not displaying teams", () => multiplayerScreenStack.ChildrenOfType().All(d => d.DisplayedTeam == null));
+
AddStep("change to team vs", () => client.ChangeSettings(matchType: MatchType.TeamVersus));
AddAssert("room type is team vs", () => client.Room?.Settings.MatchType == MatchType.TeamVersus);
+
+ AddUntilStep("team displays are displaying teams", () => multiplayerScreenStack.ChildrenOfType().All(d => d.DisplayedTeam != null));
}
private void createRoom(Func room)
diff --git a/osu.Game.Tests/Visual/Online/TestSceneAccountCreationOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneAccountCreationOverlay.cs
index 06cc613c17..8f0da8d182 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneAccountCreationOverlay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneAccountCreationOverlay.cs
@@ -8,6 +8,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.AccountCreation;
using osu.Game.Overlays.Settings;
@@ -20,7 +21,7 @@ namespace osu.Game.Tests.Visual.Online
private readonly Container userPanelArea;
private readonly AccountCreationOverlay accountCreation;
- private IBindable localUser;
+ private IBindable localUser;
public TestSceneAccountCreationOverlay()
{
diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs
index c7a065fdd7..cbb6dce4d6 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs
@@ -14,8 +14,8 @@ using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.BeatmapListing;
using osu.Game.Scoring;
-using osu.Game.Users;
using osuTK.Input;
+using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Tests.Visual.Online
{
@@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Online
};
// non-supporter user
- api.LocalUser.Value = new User
+ api.LocalUser.Value = new APIUser
{
Username = "TestBot",
Id = API.LocalUser.Value.Id + 1,
diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs
index 63ce057667..86863c0b5d 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs
@@ -7,11 +7,11 @@ using osu.Game.Beatmaps;
using osu.Game.Overlays;
using osu.Game.Overlays.BeatmapSet;
using osu.Game.Rulesets;
-using osu.Game.Users;
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Online.API.Requests.Responses;
+using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Tests.Visual.Online
{
@@ -56,7 +56,7 @@ namespace osu.Game.Tests.Visual.Online
Artist = @"naru narusegawa",
Source = @"hinata sou",
Tags = @"test tag tag more tag",
- Author = new User
+ Author = new APIUser
{
Username = @"BanchoBot",
Id = 3,
diff --git a/osu.Game.Tests/Visual/Online/TestSceneChannelTabControl.cs b/osu.Game.Tests/Visual/Online/TestSceneChannelTabControl.cs
index 73e1fc9b35..e6eaffc4c1 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneChannelTabControl.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneChannelTabControl.cs
@@ -11,9 +11,9 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Utils;
using osu.Game.Graphics.Sprites;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Chat;
using osu.Game.Overlays.Chat.Tabs;
-using osu.Game.Users;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Online
@@ -108,7 +108,7 @@ namespace osu.Game.Tests.Visual.Online
}
private void addRandomPrivateChannel() =>
- channelTabControl.AddChannel(new Channel(new User
+ channelTabControl.AddChannel(new Channel(new APIUser
{
Id = RNG.Next(1000, 10000000),
Username = "Test User " + RNG.Next(1000)
diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLineTruncation.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLineTruncation.cs
index 8408b7dd60..444bd7e5fb 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneChatLineTruncation.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneChatLineTruncation.cs
@@ -6,9 +6,9 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Chat;
using osu.Game.Overlays.Chat;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Online
{
@@ -55,14 +55,14 @@ namespace osu.Game.Tests.Visual.Online
{
private static long messageCounter;
- internal static readonly User TEST_SENDER_BACKGROUND = new User
+ internal static readonly APIUser TEST_SENDER_BACKGROUND = new APIUser
{
Username = @"i-am-important",
Id = 42,
Colour = "#250cc9",
};
- internal static readonly User TEST_SENDER = new User
+ internal static readonly APIUser TEST_SENDER = new APIUser
{
Username = @"Somebody",
Id = 1,
@@ -75,7 +75,7 @@ namespace osu.Game.Tests.Visual.Online
{
Content = text;
IsAction = isAction;
- Sender = new User
+ Sender = new APIUser
{
Username = username ?? $"user {number}",
Id = number,
diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs
index 74f53ebdca..a03c00eb58 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs
@@ -10,10 +10,10 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Chat;
using osu.Game.Overlays;
using osu.Game.Overlays.Chat;
-using osu.Game.Users;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Online
@@ -168,14 +168,14 @@ namespace osu.Game.Tests.Visual.Online
{
private static long messageCounter;
- internal static readonly User TEST_SENDER_BACKGROUND = new User
+ internal static readonly APIUser TEST_SENDER_BACKGROUND = new APIUser
{
Username = @"i-am-important",
Id = 42,
Colour = "#250cc9",
};
- internal static readonly User TEST_SENDER = new User
+ internal static readonly APIUser TEST_SENDER = new APIUser
{
Username = @"Somebody",
Id = 1,
@@ -188,7 +188,7 @@ namespace osu.Game.Tests.Visual.Online
{
Content = text;
IsAction = isAction;
- Sender = new User
+ Sender = new APIUser
{
Username = $"User {number}",
Id = number,
diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs
index 99c3b398ab..7028ecf39f 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs
@@ -18,12 +18,12 @@ using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Chat;
using osu.Game.Overlays;
using osu.Game.Overlays.Chat;
using osu.Game.Overlays.Chat.Selection;
using osu.Game.Overlays.Chat.Tabs;
-using osu.Game.Users;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Online
@@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Online
public TestSceneChatOverlay()
{
channels = Enumerable.Range(1, 10)
- .Select(index => new Channel(new User())
+ .Select(index => new Channel(new APIUser())
{
Name = $"Channel no. {index}",
Topic = index == 3 ? null : $"We talk about the number {index} here",
@@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual.Online
case GetUserRequest getUser:
if (getUser.Lookup.Equals("some body", StringComparison.OrdinalIgnoreCase))
{
- getUser.TriggerSuccess(new User
+ getUser.TriggerSuccess(new APIUser
{
Username = "some body",
Id = 1,
@@ -149,7 +149,7 @@ namespace osu.Game.Tests.Visual.Online
{
ChannelId = channel1.Id,
Content = "hello from channel 1!",
- Sender = new User
+ Sender = new APIUser
{
Id = 2,
Username = "test_user"
diff --git a/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs
index 2f11fec6d1..b5a03b558d 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs
@@ -9,6 +9,7 @@ using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Database;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Spectator;
using osu.Game.Overlays.Dashboard;
using osu.Game.Tests.Visual.Spectator;
@@ -18,7 +19,7 @@ namespace osu.Game.Tests.Visual.Online
{
public class TestSceneCurrentlyPlayingDisplay : OsuTestScene
{
- private readonly User streamingUser = new User { Id = 2, Username = "Test user" };
+ private readonly APIUser streamingUser = new APIUser { Id = 2, Username = "Test user" };
private TestSpectatorClient spectatorClient;
private CurrentlyPlayingDisplay currentlyPlaying;
@@ -83,13 +84,13 @@ namespace osu.Game.Tests.Visual.Online
"pishifat"
};
- protected override Task ComputeValueAsync(int lookup, CancellationToken token = default)
+ protected override Task ComputeValueAsync(int lookup, CancellationToken token = default)
{
// tests against failed lookups
if (lookup == 13)
- return Task.FromResult(null);
+ return Task.FromResult(null);
- return Task.FromResult(new User
+ return Task.FromResult(new APIUser
{
Id = lookup,
Username = usernames[lookup % usernames.Length],
diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs
index 3d828077c8..a865bbe950 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs
@@ -45,10 +45,10 @@ namespace osu.Game.Tests.Visual.Online
AddStep("import soleily", () => beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()));
AddUntilStep("wait for beatmap import", () => beatmaps.GetAllUsableBeatmapSets().Any(b => b.OnlineBeatmapSetID == 241526));
- AddAssert("button state downloaded", () => downloadButton.DownloadState == DownloadState.LocallyAvailable);
+ AddUntilStep("button state downloaded", () => downloadButton.DownloadState == DownloadState.LocallyAvailable);
createButtonWithBeatmap(createSoleily());
- AddAssert("button state downloaded", () => downloadButton.DownloadState == DownloadState.LocallyAvailable);
+ AddUntilStep("button state downloaded", () => downloadButton.DownloadState == DownloadState.LocallyAvailable);
ensureSoleilyRemoved();
AddAssert("button state not downloaded", () => downloadButton.DownloadState == DownloadState.NotDownloaded);
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs
index a3c8935fa8..01dde97d38 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs
@@ -10,8 +10,8 @@ using osu.Game.Beatmaps;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.BeatmapListing.Panels;
using osu.Game.Rulesets;
-using osu.Game.Users;
using osuTK;
+using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Tests.Visual.Online
{
@@ -74,7 +74,7 @@ namespace osu.Game.Tests.Visual.Online
Title = "undownloadable beatmap",
Artist = "test",
Source = "more tests",
- Author = new User
+ Author = new APIUser
{
Username = "BanchoBot",
Id = 3,
@@ -121,7 +121,7 @@ namespace osu.Game.Tests.Visual.Online
Title = "undownloadable beatmap",
Artist = "test",
Source = "more tests",
- Author = new User
+ Author = new APIUser
{
Username = "BanchoBot",
Id = 3,
diff --git a/osu.Game.Tests/Visual/Online/TestSceneFriendDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneFriendDisplay.cs
index e8d9ff72af..471d361c4e 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneFriendDisplay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneFriendDisplay.cs
@@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Dashboard.Friends;
using osu.Game.Users;
@@ -44,9 +45,9 @@ namespace osu.Game.Tests.Visual.Online
// No need to do anything, fetch is performed automatically.
}
- private List getUsers() => new List
+ private List getUsers() => new List
{
- new User
+ new APIUser
{
Username = "flyte",
Id = 3103765,
@@ -55,7 +56,7 @@ namespace osu.Game.Tests.Visual.Online
Country = new Country { FlagName = "JP" },
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c6.jpg"
},
- new User
+ new APIUser
{
Username = "peppy",
Id = 2,
@@ -66,7 +67,7 @@ namespace osu.Game.Tests.Visual.Online
IsSupporter = true,
SupportLevel = 3,
},
- new User
+ new APIUser
{
Username = "Evast",
Id = 8195163,
diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs
index 3ecca85ef1..2639a6506c 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs
@@ -7,9 +7,9 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Profile.Sections;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Online
{
@@ -37,8 +37,8 @@ namespace osu.Game.Tests.Visual.Online
Child = section = new HistoricalSection(),
});
- AddStep("Show peppy", () => section.User.Value = new User { Id = 2 });
- AddStep("Show WubWoofWolf", () => section.User.Value = new User { Id = 39828 });
+ AddStep("Show peppy", () => section.User.Value = new APIUser { Id = 2 });
+ AddStep("Show WubWoofWolf", () => section.User.Value = new APIUser { Id = 39828 });
}
}
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs b/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs
index d193856217..175d2ea36b 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs
@@ -15,14 +15,14 @@ using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Chat;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
-using osu.Game.Users;
using osuTK.Input;
+using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Tests.Visual.Online
{
public class TestSceneMessageNotifier : OsuManualInputManagerTestScene
{
- private User friend;
+ private APIUser friend;
private Channel publicChannel;
private Channel privateMessageChannel;
private TestContainer testContainer;
@@ -37,7 +37,7 @@ namespace osu.Game.Tests.Visual.Online
daa.HandleRequest = dummyAPIHandleRequest;
}
- friend = new User { Id = 0, Username = "Friend" };
+ friend = new APIUser { Id = 0, Username = "Friend" };
publicChannel = new Channel { Id = 1, Name = "osu" };
privateMessageChannel = new Channel(friend) { Id = 2, Name = friend.Username, Type = ChannelType.PM };
@@ -178,9 +178,9 @@ namespace osu.Game.Tests.Visual.Online
AddAssert("1 notification fired", () => testContainer.NotificationOverlay.UnreadCount.Value == 1);
}
- private void receiveMessage(User sender, Channel channel, string content) => channel.AddNewMessages(createMessage(sender, channel, content));
+ private void receiveMessage(APIUser sender, Channel channel, string content) => channel.AddNewMessages(createMessage(sender, channel, content));
- private Message createMessage(User sender, Channel channel, string content) => new Message(messageIdCounter++)
+ private Message createMessage(APIUser sender, Channel channel, string content) => new Message(messageIdCounter++)
{
Content = content,
Sender = sender,
diff --git a/osu.Game.Tests/Visual/Online/TestSceneOfflineCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOfflineCommentsContainer.cs
index 4f7947b69c..0587e8884f 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneOfflineCommentsContainer.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneOfflineCommentsContainer.cs
@@ -11,9 +11,9 @@ using osu.Game.Overlays.Comments;
using osu.Game.Overlays;
using osu.Framework.Allocation;
using osu.Game.Online.API.Requests.Responses;
-using osu.Game.Users;
using JetBrains.Annotations;
using osu.Framework.Testing;
+using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Tests.Visual.Online
{
@@ -154,9 +154,9 @@ namespace osu.Game.Tests.Visual.Online
{
5
},
- Users = new List
+ Users = new List
{
- new User
+ new APIUser
{
Id = 1,
Username = "Good_Admin"
diff --git a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs
index cf5ecf5bf2..fecc1af03c 100644
--- a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs
+++ b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs
@@ -4,7 +4,6 @@
using osu.Game.Overlays.Profile.Sections.Historical;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
-using osu.Game.Users;
using NUnit.Framework;
using osu.Game.Overlays;
using osu.Framework.Allocation;
@@ -12,7 +11,7 @@ using System;
using System.Linq;
using osu.Framework.Testing;
using osu.Framework.Graphics.Shapes;
-using static osu.Game.Users.User;
+using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Tests.Visual.Online
{
@@ -21,7 +20,7 @@ namespace osu.Game.Tests.Visual.Online
[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red);
- private readonly Bindable user = new Bindable();
+ private readonly Bindable user = new Bindable();
private readonly PlayHistorySubsection section;
public TestScenePlayHistorySubsection()
@@ -101,80 +100,80 @@ namespace osu.Game.Tests.Visual.Online
private int getChartValuesLength() => this.ChildrenOfType().Single().Values.Length;
- private static readonly User user_with_null_values = new User
+ private static readonly APIUser user_with_null_values = new APIUser
{
Id = 1
};
- private static readonly User user_with_empty_values = new User
+ private static readonly APIUser user_with_empty_values = new APIUser
{
Id = 2,
- MonthlyPlaycounts = Array.Empty()
+ MonthlyPlaycounts = Array.Empty()
};
- private static readonly User user_with_one_value = new User
+ private static readonly APIUser user_with_one_value = new APIUser
{
Id = 3,
MonthlyPlaycounts = new[]
{
- new UserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 100 }
+ new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 100 }
}
};
- private static readonly User user_with_two_values = new User
+ private static readonly APIUser user_with_two_values = new APIUser
{
Id = 4,
MonthlyPlaycounts = new[]
{
- new UserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 1 },
- new UserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 2 }
+ new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 1 },
+ new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 2 }
}
};
- private static readonly User user_with_constant_values = new User
+ private static readonly APIUser user_with_constant_values = new APIUser
{
Id = 5,
MonthlyPlaycounts = new[]
{
- new UserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 5 },
- new UserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 5 },
- new UserHistoryCount { Date = new DateTime(2010, 7, 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, 7, 1), Count = 5 }
}
};
- private static readonly User user_with_zero_values = new User
+ private static readonly APIUser user_with_zero_values = new APIUser
{
Id = 6,
MonthlyPlaycounts = new[]
{
- new UserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 0 },
- new UserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 0 },
- new UserHistoryCount { Date = new DateTime(2010, 7, 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, 7, 1), Count = 0 }
}
};
- private static readonly User user_with_filled_values = new User
+ private static readonly APIUser user_with_filled_values = new APIUser
{
Id = 7,
MonthlyPlaycounts = new[]
{
- new UserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 1000 },
- new UserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 20 },
- new UserHistoryCount { Date = new DateTime(2010, 7, 1), Count = 20000 },
- new UserHistoryCount { Date = new DateTime(2010, 8, 1), Count = 30 },
- new UserHistoryCount { Date = new DateTime(2010, 9, 1), Count = 50 },
- new UserHistoryCount { Date = new DateTime(2010, 10, 1), Count = 2000 },
- new UserHistoryCount { Date = new DateTime(2010, 11, 1), Count = 2100 }
+ 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, 7, 1), Count = 20000 },
+ new APIUserHistoryCount { Date = new DateTime(2010, 8, 1), Count = 30 },
+ new APIUserHistoryCount { Date = new DateTime(2010, 9, 1), Count = 50 },
+ new APIUserHistoryCount { Date = new DateTime(2010, 10, 1), Count = 2000 },
+ new APIUserHistoryCount { Date = new DateTime(2010, 11, 1), Count = 2100 }
}
};
- private static readonly User user_with_missing_values = new User
+ private static readonly APIUser user_with_missing_values = new APIUser
{
Id = 8,
MonthlyPlaycounts = new[]
{
- new UserHistoryCount { Date = new DateTime(2020, 1, 1), Count = 100 },
- new UserHistoryCount { Date = new DateTime(2020, 7, 1), Count = 200 }
+ new APIUserHistoryCount { Date = new DateTime(2020, 1, 1), Count = 100 },
+ new APIUserHistoryCount { Date = new DateTime(2020, 7, 1), Count = 200 }
}
};
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs
index 6a847e4269..cbbe8b8eac 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs
@@ -7,10 +7,10 @@ using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Taiko;
-using osu.Game.Users;
using osu.Framework.Bindables;
using osu.Game.Overlays;
using osu.Framework.Allocation;
+using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Tests.Visual.Online
{
@@ -22,7 +22,7 @@ namespace osu.Game.Tests.Visual.Online
public TestSceneProfileRulesetSelector()
{
ProfileRulesetSelector selector;
- var user = new Bindable();
+ var user = new Bindable();
Child = selector = new ProfileRulesetSelector
{
@@ -36,10 +36,10 @@ namespace osu.Game.Tests.Visual.Online
AddStep("set taiko as default", () => selector.SetDefaultRuleset(new TaikoRuleset().RulesetInfo));
AddStep("set catch as default", () => selector.SetDefaultRuleset(new CatchRuleset().RulesetInfo));
- AddStep("User with osu as default", () => user.Value = new User { PlayMode = "osu" });
- AddStep("User with mania as default", () => user.Value = new User { PlayMode = "mania" });
- AddStep("User with taiko as default", () => user.Value = new User { PlayMode = "taiko" });
- AddStep("User with catch as default", () => user.Value = new User { PlayMode = "fruits" });
+ AddStep("User with osu as default", () => user.Value = new APIUser { PlayMode = "osu" });
+ AddStep("User with mania as default", () => user.Value = new APIUser { PlayMode = "mania" });
+ AddStep("User with taiko as default", () => user.Value = new APIUser { PlayMode = "taiko" });
+ AddStep("User with catch as default", () => user.Value = new APIUser { PlayMode = "fruits" });
AddStep("null user", () => user.Value = null);
}
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs
index f577140e17..61574a7f23 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs
@@ -7,6 +7,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Profile.Header.Components;
using osu.Game.Users;
@@ -81,7 +82,7 @@ namespace osu.Game.Tests.Visual.Online
{
GlobalRank = 89000,
PP = 12345,
- RankHistory = new User.RankHistoryData
+ RankHistory = new APIRankHistory
{
Data = data,
}
@@ -94,7 +95,7 @@ namespace osu.Game.Tests.Visual.Online
{
GlobalRank = 89000,
PP = 12345,
- RankHistory = new User.RankHistoryData
+ RankHistory = new APIRankHistory
{
Data = dataWithZeros,
}
@@ -107,7 +108,7 @@ namespace osu.Game.Tests.Visual.Online
{
GlobalRank = 12000,
PP = 12345,
- RankHistory = new User.RankHistoryData
+ RankHistory = new APIRankHistory
{
Data = smallData,
}
@@ -120,7 +121,7 @@ namespace osu.Game.Tests.Visual.Online
{
GlobalRank = 12000,
PP = 12345,
- RankHistory = new User.RankHistoryData
+ RankHistory = new APIRankHistory
{
Data = edgyData,
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs
index 23899154c4..50969aad9b 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs
@@ -15,6 +15,7 @@ using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Scoring;
using osu.Game.Users;
using osuTK.Graphics;
+using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Tests.Visual.Online
{
@@ -50,7 +51,7 @@ namespace osu.Game.Tests.Visual.Online
{
new APIScoreInfo
{
- User = new User
+ User = new APIUser
{
Id = 6602580,
Username = @"waaiiru",
@@ -75,7 +76,7 @@ namespace osu.Game.Tests.Visual.Online
},
new APIScoreInfo
{
- User = new User
+ User = new APIUser
{
Id = 4608074,
Username = @"Skycries",
@@ -99,7 +100,7 @@ namespace osu.Game.Tests.Visual.Online
},
new APIScoreInfo
{
- User = new User
+ User = new APIUser
{
Id = 1014222,
Username = @"eLy",
@@ -122,7 +123,7 @@ namespace osu.Game.Tests.Visual.Online
},
new APIScoreInfo
{
- User = new User
+ User = new APIUser
{
Id = 1541390,
Username = @"Toukai",
@@ -144,7 +145,7 @@ namespace osu.Game.Tests.Visual.Online
},
new APIScoreInfo
{
- User = new User
+ User = new APIUser
{
Id = 7151382,
Username = @"Mayuri Hana",
@@ -167,7 +168,7 @@ namespace osu.Game.Tests.Visual.Online
{
Score = new APIScoreInfo
{
- User = new User
+ User = new APIUser
{
Id = 7151382,
Username = @"Mayuri Hana",
@@ -190,7 +191,7 @@ namespace osu.Game.Tests.Visual.Online
{
Score = new APIScoreInfo
{
- User = new User
+ User = new APIUser
{
Id = 7151382,
Username = @"Mayuri Hana",
@@ -215,7 +216,7 @@ namespace osu.Game.Tests.Visual.Online
{
new APIScoreInfo
{
- User = new User
+ User = new APIUser
{
Id = 6602580,
Username = @"waaiiru",
diff --git a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs
index b3b8d75c46..b7bce012ce 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs
@@ -4,13 +4,13 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Online.Chat;
-using osu.Game.Users;
using osuTK;
using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.Containers;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Chat;
using osuTK.Input;
@@ -18,26 +18,26 @@ namespace osu.Game.Tests.Visual.Online
{
public class TestSceneStandAloneChatDisplay : OsuManualInputManagerTestScene
{
- private readonly User admin = new User
+ private readonly APIUser admin = new APIUser
{
Username = "HappyStick",
Id = 2,
Colour = "f2ca34"
};
- private readonly User redUser = new User
+ private readonly APIUser redUser = new APIUser
{
Username = "BanchoBot",
Id = 3,
};
- private readonly User blueUser = new User
+ private readonly APIUser blueUser = new APIUser
{
Username = "Zallius",
Id = 4,
};
- private readonly User longUsernameUser = new User
+ private readonly APIUser longUsernameUser = new APIUser
{
Username = "Very Long Long Username",
Id = 5,
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs b/osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs
index 484c59695e..3f4a5cd420 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs
@@ -2,11 +2,11 @@
// See the LICENCE file in the repository root for full licence text.
using System;
-using osu.Game.Overlays.Profile.Sections.Historical;
-using osu.Framework.Graphics;
-using osu.Game.Overlays;
using osu.Framework.Allocation;
-using static osu.Game.Users.User;
+using osu.Framework.Graphics;
+using osu.Game.Online.API.Requests.Responses;
+using osu.Game.Overlays;
+using osu.Game.Overlays.Profile.Sections.Historical;
namespace osu.Game.Tests.Visual.Online
{
@@ -29,28 +29,28 @@ namespace osu.Game.Tests.Visual.Online
var values = new[]
{
- new UserHistoryCount { Date = new DateTime(2000, 1, 1), Count = 10 },
- new UserHistoryCount { Date = new DateTime(2000, 2, 1), Count = 20 },
- new UserHistoryCount { Date = new DateTime(2000, 3, 1), Count = 100 },
- new UserHistoryCount { Date = new DateTime(2000, 4, 1), Count = 15 },
- new UserHistoryCount { Date = new DateTime(2000, 5, 1), Count = 30 }
+ new APIUserHistoryCount { Date = new DateTime(2000, 1, 1), Count = 10 },
+ new APIUserHistoryCount { Date = new DateTime(2000, 2, 1), Count = 20 },
+ new APIUserHistoryCount { Date = new DateTime(2000, 3, 1), Count = 100 },
+ new APIUserHistoryCount { Date = new DateTime(2000, 4, 1), Count = 15 },
+ new APIUserHistoryCount { Date = new DateTime(2000, 5, 1), Count = 30 }
};
var moreValues = new[]
{
- new UserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 1000 },
- new UserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 20 },
- new UserHistoryCount { Date = new DateTime(2010, 7, 1), Count = 20000 },
- new UserHistoryCount { Date = new DateTime(2010, 8, 1), Count = 30 },
- new UserHistoryCount { Date = new DateTime(2010, 9, 1), Count = 50 },
- new UserHistoryCount { Date = new DateTime(2010, 10, 1), Count = 2000 },
- new UserHistoryCount { Date = new DateTime(2010, 11, 1), Count = 2100 }
+ 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, 7, 1), Count = 20000 },
+ new APIUserHistoryCount { Date = new DateTime(2010, 8, 1), Count = 30 },
+ new APIUserHistoryCount { Date = new DateTime(2010, 9, 1), Count = 50 },
+ new APIUserHistoryCount { Date = new DateTime(2010, 10, 1), Count = 2000 },
+ new APIUserHistoryCount { Date = new DateTime(2010, 11, 1), Count = 2100 }
};
AddStep("Set fake values", () => graph.Values = values);
AddStep("Set more values", () => graph.Values = moreValues);
AddStep("Set null values", () => graph.Values = null);
- AddStep("Set empty values", () => graph.Values = Array.Empty());
+ AddStep("Set empty values", () => graph.Values = Array.Empty());
}
}
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs
index a048ae2c54..19e06beaad 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs
@@ -7,6 +7,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets;
using osu.Game.Users;
using osuTK;
@@ -42,27 +43,27 @@ namespace osu.Game.Tests.Visual.Online
Spacing = new Vector2(10f),
Children = new Drawable[]
{
- new UserBrickPanel(new User
+ new UserBrickPanel(new APIUser
{
Username = @"flyte",
Id = 3103765,
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg"
}),
- new UserBrickPanel(new User
+ new UserBrickPanel(new APIUser
{
Username = @"peppy",
Id = 2,
Colour = "99EB47",
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
}),
- flyte = new UserGridPanel(new User
+ flyte = new UserGridPanel(new APIUser
{
Username = @"flyte",
Id = 3103765,
Country = new Country { FlagName = @"JP" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg"
}) { Width = 300 },
- peppy = new UserGridPanel(new User
+ peppy = new UserGridPanel(new APIUser
{
Username = @"peppy",
Id = 2,
@@ -71,7 +72,7 @@ namespace osu.Game.Tests.Visual.Online
IsSupporter = true,
SupportLevel = 3,
}) { Width = 300 },
- evast = new TestUserListPanel(new User
+ evast = new TestUserListPanel(new APIUser
{
Username = @"Evast",
Id = 8195163,
@@ -134,7 +135,7 @@ namespace osu.Game.Tests.Visual.Online
private class TestUserListPanel : UserListPanel
{
- public TestUserListPanel(User user)
+ public TestUserListPanel(APIUser user)
: base(user)
{
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs
index 04b741b2bb..76997bded7 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs
@@ -5,6 +5,7 @@ using System;
using osu.Framework.Allocation;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Profile;
using osu.Game.Users;
@@ -30,26 +31,26 @@ namespace osu.Game.Tests.Visual.Online
AddStep("Show test dummy", () => header.User.Value = TestSceneUserProfileOverlay.TEST_USER);
- AddStep("Show null dummy", () => header.User.Value = new User
+ AddStep("Show null dummy", () => header.User.Value = new APIUser
{
Username = "Null"
});
- AddStep("Show online dummy", () => header.User.Value = new User
+ AddStep("Show online dummy", () => header.User.Value = new APIUser
{
Username = "IAmOnline",
LastVisit = DateTimeOffset.Now,
IsOnline = true,
});
- AddStep("Show offline dummy", () => header.User.Value = new User
+ AddStep("Show offline dummy", () => header.User.Value = new APIUser
{
Username = "IAmOffline",
LastVisit = DateTimeOffset.Now,
IsOnline = false,
});
- addOnlineStep("Show ppy", new User
+ addOnlineStep("Show ppy", new APIUser
{
Username = @"peppy",
Id = 2,
@@ -58,7 +59,7 @@ namespace osu.Game.Tests.Visual.Online
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg"
});
- addOnlineStep("Show flyte", new User
+ addOnlineStep("Show flyte", new APIUser
{
Username = @"flyte",
Id = 3103765,
@@ -67,7 +68,7 @@ namespace osu.Game.Tests.Visual.Online
});
}
- private void addOnlineStep(string name, User fallback)
+ private void addOnlineStep(string name, APIUser fallback)
{
AddStep(name, () =>
{
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs
index 70271b0b08..ce8136199f 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs
@@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Game.Online.API;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Profile;
using osu.Game.Users;
@@ -22,7 +23,7 @@ namespace osu.Game.Tests.Visual.Online
[Resolved]
private IAPIProvider api { get; set; }
- public static readonly User TEST_USER = new User
+ public static readonly APIUser TEST_USER = new APIUser
{
Username = @"Somebody",
Id = 1,
@@ -41,7 +42,7 @@ namespace osu.Game.Tests.Visual.Online
Current = 727,
Progress = 69,
},
- RankHistory = new User.RankHistoryData
+ RankHistory = new APIRankHistory
{
Mode = @"osu",
Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray()
@@ -58,7 +59,7 @@ namespace osu.Game.Tests.Visual.Online
},
Title = "osu!volunteer",
Colour = "ff0000",
- Achievements = Array.Empty(),
+ Achievements = Array.Empty(),
};
public TestSceneUserProfileOverlay()
@@ -70,42 +71,42 @@ namespace osu.Game.Tests.Visual.Online
{
base.LoadComplete();
- AddStep("Show offline dummy", () => profile.ShowUser(TEST_USER, false));
+ AddStep("Show offline dummy", () => profile.ShowUser(TEST_USER));
- AddStep("Show null dummy", () => profile.ShowUser(new User
+ AddStep("Show null dummy", () => profile.ShowUser(new APIUser
{
Username = @"Null",
Id = 1,
- }, false));
+ }));
- AddStep("Show ppy", () => profile.ShowUser(new User
+ AddStep("Show ppy", () => profile.ShowUser(new APIUser
{
Username = @"peppy",
Id = 2,
IsSupporter = true,
Country = new Country { FullName = @"Australia", FlagName = @"AU" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg"
- }, api.IsLoggedIn));
+ }));
- AddStep("Show flyte", () => profile.ShowUser(new User
+ AddStep("Show flyte", () => profile.ShowUser(new APIUser
{
Username = @"flyte",
Id = 3103765,
Country = new Country { FullName = @"Japan", FlagName = @"JP" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg"
- }, api.IsLoggedIn));
+ }));
- AddStep("Show bancho", () => profile.ShowUser(new User
+ AddStep("Show bancho", () => profile.ShowUser(new APIUser
{
Username = @"BanchoBot",
Id = 3,
IsBot = true,
Country = new Country { FullName = @"Saint Helena", FlagName = @"SH" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c4.jpg"
- }, api.IsLoggedIn));
+ }));
- AddStep("Show ppy from username", () => profile.ShowUser(@"peppy"));
- AddStep("Show flyte from username", () => profile.ShowUser(@"flyte"));
+ AddStep("Show ppy from username", () => profile.ShowUser(new APIUser { Username = @"peppy" }));
+ AddStep("Show flyte from username", () => profile.ShowUser(new APIUser { Username = @"flyte" }));
AddStep("Hide", profile.Hide);
AddStep("Show without reload", profile.Show);
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs
index b5d2d15392..30774689a2 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs
@@ -4,8 +4,8 @@
using System;
using NUnit.Framework;
using osu.Framework.Graphics;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Profile.Header.Components;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Online
{
@@ -48,13 +48,13 @@ namespace osu.Game.Tests.Visual.Online
AddUntilStep("Is hidden", () => container.Alpha == 0);
}
- private static readonly User[] users =
+ private static readonly APIUser[] users =
{
- new User { Id = 1, PreviousUsernames = new[] { "username1" } },
- new User { Id = 2, PreviousUsernames = new[] { "longusername", "longerusername" } },
- new User { Id = 3, PreviousUsernames = new[] { "test", "angelsim", "verylongusername" } },
- new User { Id = 4, PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger" } },
- new User { Id = 5, PreviousUsernames = Array.Empty() },
+ new APIUser { Id = 1, PreviousUsernames = new[] { "username1" } },
+ new APIUser { Id = 2, PreviousUsernames = new[] { "longusername", "longerusername" } },
+ new APIUser { Id = 3, PreviousUsernames = new[] { "test", "angelsim", "verylongusername" } },
+ new APIUser { Id = 4, PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger" } },
+ new APIUser { Id = 5, PreviousUsernames = Array.Empty() },
null
};
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs
index c22cff4af6..b9272e7294 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs
@@ -8,9 +8,9 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Profile.Sections;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Online
{
@@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual.Online
}
});
- AddStep("Show cookiezi", () => ranks.User.Value = new User { Id = 124493 });
+ AddStep("Show cookiezi", () => ranks.User.Value = new APIUser { Id = 124493 });
}
}
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRequest.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRequest.cs
index 15cfd3ee54..e7b6a94642 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserRequest.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserRequest.cs
@@ -9,10 +9,10 @@ using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mania;
-using osu.Game.Users;
using osu.Framework.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Taiko;
namespace osu.Game.Tests.Visual.Online
@@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Online
[Resolved]
private IAPIProvider api { get; set; }
- private readonly Bindable user = new Bindable();
+ private readonly Bindable user = new Bindable();
private GetUserRequest request;
private readonly LoadingLayer loading;
@@ -71,7 +71,7 @@ namespace osu.Game.Tests.Visual.Online
private class UserTestContainer : FillFlowContainer
{
- public readonly Bindable User = new Bindable();
+ public readonly Bindable User = new Bindable();
public UserTestContainer()
{
@@ -85,7 +85,7 @@ namespace osu.Game.Tests.Visual.Online
User.BindValueChanged(onUserUpdate, true);
}
- private void onUserUpdate(ValueChangedEvent user)
+ private void onUserUpdate(ValueChangedEvent user)
{
Clear();
diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsParticipantsList.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsParticipantsList.cs
index 76a78c0a3c..1288b9e765 100644
--- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsParticipantsList.cs
+++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsParticipantsList.cs
@@ -3,6 +3,7 @@
using NUnit.Framework;
using osu.Framework.Graphics;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osu.Game.Screens.OnlinePlay.Components;
using osu.Game.Tests.Visual.OnlinePlay;
@@ -19,7 +20,7 @@ namespace osu.Game.Tests.Visual.Playlists
for (int i = 0; i < 50; i++)
{
- SelectedRoom.Value.RecentParticipants.Add(new User
+ SelectedRoom.Value.RecentParticipants.Add(new APIUser
{
Username = "peppy",
Statistics = new UserStatistics { GlobalRank = 1234 },
diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsResultsScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsResultsScreen.cs
index d948aebbbf..4284bc6358 100644
--- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsResultsScreen.cs
+++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsResultsScreen.cs
@@ -14,6 +14,7 @@ using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Scoring;
@@ -21,7 +22,6 @@ using osu.Game.Scoring;
using osu.Game.Screens.OnlinePlay.Playlists;
using osu.Game.Screens.Ranking;
using osu.Game.Tests.Beatmaps;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.Playlists
{
@@ -260,7 +260,7 @@ namespace osu.Game.Tests.Visual.Playlists
Rank = userScore.Rank,
MaxCombo = userScore.MaxCombo,
TotalScore = userScore.TotalScore - i,
- User = new User
+ User = new APIUser
{
Id = 2,
Username = $"peppy{i}",
@@ -278,7 +278,7 @@ namespace osu.Game.Tests.Visual.Playlists
Rank = userScore.Rank,
MaxCombo = userScore.MaxCombo,
TotalScore = userScore.TotalScore + i,
- User = new User
+ User = new APIUser
{
Id = 2,
Username = $"peppy{i}",
@@ -314,7 +314,7 @@ namespace osu.Game.Tests.Visual.Playlists
Rank = ScoreRank.X,
MaxCombo = 1000,
TotalScore = startTotalScore + (sort == "score_asc" ? i : -i),
- User = new User
+ User = new APIUser
{
Id = 2,
Username = $"peppy{i}",
diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneAccuracyCircle.cs b/osu.Game.Tests/Visual/Ranking/TestSceneAccuracyCircle.cs
index df8500fab2..944941723e 100644
--- a/osu.Game.Tests/Visual/Ranking/TestSceneAccuracyCircle.cs
+++ b/osu.Game.Tests/Visual/Ranking/TestSceneAccuracyCircle.cs
@@ -8,6 +8,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
@@ -15,7 +16,6 @@ using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Screens.Ranking.Expanded.Accuracy;
using osu.Game.Tests.Beatmaps;
-using osu.Game.Users;
using osuTK;
namespace osu.Game.Tests.Visual.Ranking
@@ -66,7 +66,7 @@ namespace osu.Game.Tests.Visual.Ranking
private ScoreInfo createScore(double accuracy, ScoreRank rank) => new ScoreInfo
{
- User = new User
+ User = new APIUser
{
Id = 2,
Username = "peppy",
diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneExpandedPanelMiddleContent.cs b/osu.Game.Tests/Visual/Ranking/TestSceneExpandedPanelMiddleContent.cs
index 899f351a2a..9983993d9c 100644
--- a/osu.Game.Tests/Visual/Ranking/TestSceneExpandedPanelMiddleContent.cs
+++ b/osu.Game.Tests/Visual/Ranking/TestSceneExpandedPanelMiddleContent.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
+using JetBrains.Annotations;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
@@ -11,6 +12,7 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Sprites;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
@@ -18,7 +20,6 @@ using osu.Game.Scoring;
using osu.Game.Screens.Ranking;
using osu.Game.Screens.Ranking.Expanded;
using osu.Game.Tests.Beatmaps;
-using osu.Game.Users;
using osuTK;
namespace osu.Game.Tests.Visual.Ranking
@@ -31,7 +32,7 @@ namespace osu.Game.Tests.Visual.Ranking
[Test]
public void TestMapWithKnownMapper()
{
- var author = new User { Username = "mapper_name" };
+ var author = new APIUser { Username = "mapper_name" };
AddStep("show example score", () => showPanel(new TestScoreInfo(new OsuRuleset().RulesetInfo)
{
@@ -42,7 +43,7 @@ namespace osu.Game.Tests.Visual.Ranking
[Test]
public void TestExcessMods()
{
- var author = new User { Username = "mapper_name" };
+ var author = new APIUser { Username = "mapper_name" };
AddStep("show excess mods score", () => showPanel(new TestScoreInfo(new OsuRuleset().RulesetInfo, true)
{
@@ -57,7 +58,7 @@ namespace osu.Game.Tests.Visual.Ranking
{
AddStep("show example score", () => showPanel(new TestScoreInfo(new OsuRuleset().RulesetInfo)
{
- BeatmapInfo = createTestBeatmap(null)
+ BeatmapInfo = createTestBeatmap(new APIUser())
}));
AddAssert("mapped by text not present", () =>
@@ -74,7 +75,7 @@ namespace osu.Game.Tests.Visual.Ranking
var ruleset = new OsuRuleset();
var mods = new Mod[] { ruleset.GetAutoplayMod() };
- var beatmap = createTestBeatmap(null);
+ var beatmap = createTestBeatmap(new APIUser());
showPanel(new TestScoreInfo(ruleset.RulesetInfo)
{
@@ -90,7 +91,7 @@ namespace osu.Game.Tests.Visual.Ranking
private void showPanel(ScoreInfo score) =>
Child = new ExpandedPanelMiddleContentContainer(score);
- private BeatmapInfo createTestBeatmap(User author)
+ private BeatmapInfo createTestBeatmap([NotNull] APIUser author)
{
var beatmap = new TestBeatmap(rulesetStore.GetRuleset(0)).BeatmapInfo;
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs
index 7a38d213d9..9a142f3ca8 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs
@@ -400,7 +400,7 @@ namespace osu.Game.Tests.Visual.SongSelect
loadBeatmaps();
AddStep("Sort by author", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Author }, false));
- AddAssert("Check zzzzz is at bottom", () => carousel.BeatmapSets.Last().Metadata.AuthorString == "zzzzz");
+ AddAssert("Check zzzzz is at bottom", () => carousel.BeatmapSets.Last().Metadata.Author.Username == "zzzzz");
AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false));
AddAssert($"Check #{set_count} is at bottom", () => carousel.BeatmapSets.Last().Metadata.Title.EndsWith($"#{set_count}!", StringComparison.Ordinal));
}
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
index 13b769c80a..855a59b5f5 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
@@ -10,6 +10,7 @@ using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Leaderboards;
using osu.Game.Overlays;
using osu.Game.Rulesets;
@@ -133,7 +134,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock() },
- User = new User
+ User = new APIUser
{
Id = 6602580,
Username = @"waaiiru",
@@ -156,7 +157,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
- User = new User
+ User = new APIUser
{
Id = 6602580,
Username = @"waaiiru",
@@ -198,7 +199,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- User = new User
+ User = new APIUser
{
Id = 6602580,
Username = @"waaiiru",
@@ -217,7 +218,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- User = new User
+ User = new APIUser
{
Id = 4608074,
Username = @"Skycries",
@@ -236,7 +237,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- User = new User
+ User = new APIUser
{
Id = 1014222,
Username = @"eLy",
@@ -255,7 +256,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- User = new User
+ User = new APIUser
{
Id = 1541390,
Username = @"Toukai",
@@ -274,7 +275,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- User = new User
+ User = new APIUser
{
Id = 2243452,
Username = @"Satoruu",
@@ -293,7 +294,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- User = new User
+ User = new APIUser
{
Id = 2705430,
Username = @"Mooha",
@@ -312,7 +313,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- User = new User
+ User = new APIUser
{
Id = 7151382,
Username = @"Mayuri Hana",
@@ -331,7 +332,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- User = new User
+ User = new APIUser
{
Id = 2051389,
Username = @"FunOrange",
@@ -350,7 +351,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- User = new User
+ User = new APIUser
{
Id = 6169483,
Username = @"-Hebel-",
@@ -369,7 +370,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1707827,
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
BeatmapInfo = beatmapInfo,
- User = new User
+ User = new APIUser
{
Id = 6702666,
Username = @"prhtnsm",
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs
index c22b6a54e9..68d5836cac 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs
@@ -9,6 +9,7 @@ using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Mania;
@@ -40,9 +41,9 @@ namespace osu.Game.Tests.Visual.SongSelect
base.SetUpSteps();
- User getUser(int? rulesetID)
+ APIUser getUser(int? rulesetID)
{
- return new User
+ return new APIUser
{
Username = @"Dummy",
Id = 1001,
diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs
index 4811fc979e..4861354921 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs
@@ -18,6 +18,7 @@ using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
@@ -29,7 +30,6 @@ using osu.Game.Screens.Play;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Carousel;
using osu.Game.Screens.Select.Filter;
-using osu.Game.Users;
using osuTK.Input;
namespace osu.Game.Tests.Visual.SongSelect
@@ -807,7 +807,7 @@ namespace osu.Game.Tests.Visual.SongSelect
songSelect.PresentScore(new ScoreInfo
{
- User = new User { Username = "woo" },
+ User = new APIUser { Username = "woo" },
BeatmapInfo = getPresentBeatmap(),
Ruleset = getPresentBeatmap().Ruleset
});
@@ -839,7 +839,7 @@ namespace osu.Game.Tests.Visual.SongSelect
songSelect.PresentScore(new ScoreInfo
{
- User = new User { Username = "woo" },
+ User = new APIUser { Username = "woo" },
BeatmapInfo = getPresentBeatmap(),
Ruleset = getPresentBeatmap().Ruleset
});
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs
index b8b8792b9b..7af9e9eb40 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs
@@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
+using osu.Game.Online.API.Requests.Responses;
using osuTK.Graphics;
using osu.Game.Online.Leaderboards;
using osu.Game.Overlays;
@@ -60,7 +61,7 @@ namespace osu.Game.Tests.Visual.SongSelect
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
- User = new User
+ User = new APIUser
{
Id = 6602580,
Username = @"waaiiru",
@@ -78,7 +79,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
- User = new User
+ User = new APIUser
{
Id = 4608074,
Username = @"Skycries",
@@ -96,7 +97,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
- User = new User
+ User = new APIUser
{
Id = 1541390,
Username = @"Toukai",
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs
index 06c64a566e..17ac812eb0 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs
@@ -7,11 +7,11 @@ using osu.Game.Overlays.Dashboard.Home;
using osu.Game.Beatmaps;
using osu.Game.Overlays;
using osu.Framework.Allocation;
-using osu.Game.Users;
using System;
using osu.Framework.Graphics.Shapes;
using System.Collections.Generic;
using osu.Game.Online.API.Requests.Responses;
+using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Tests.Visual.UserInterface
{
@@ -62,7 +62,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
Title = "Very Long Title (TV size) [TATOE]",
Artist = "This artist has a really long name how is this possible",
- Author = new User
+ Author = new APIUser
{
Username = "author",
Id = 100
@@ -77,7 +77,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
Title = "Very Long Title (TV size) [TATOE]",
Artist = "This artist has a really long name how is this possible",
- Author = new User
+ Author = new APIUser
{
Username = "author",
Id = 100
@@ -96,7 +96,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
Title = "Very Long Title (TV size) [TATOE]",
Artist = "This artist has a really long name how is this possible",
- Author = new User
+ Author = new APIUser
{
Username = "author",
Id = 100
@@ -111,7 +111,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
Title = "Very Long Title (TV size) [TATOE]",
Artist = "This artist has a really long name how is this possible",
- Author = new User
+ Author = new APIUser
{
Username = "author",
Id = 100
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs
index 9a75d3c309..07759d598e 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs
@@ -15,13 +15,13 @@ using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Leaderboards;
using osu.Game.Overlays;
using osu.Game.Rulesets;
using osu.Game.Scoring;
using osu.Game.Screens.Select.Leaderboards;
using osu.Game.Tests.Resources;
-using osu.Game.Users;
using osuTK;
using osuTK.Input;
@@ -64,7 +64,7 @@ namespace osu.Game.Tests.Visual.UserInterface
ID = 1,
Title = "TestSong",
Artist = "TestArtist",
- Author = new User
+ Author = new APIUser
{
Username = "TestAuthor"
},
@@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual.UserInterface
TotalScore = RNG.Next(1, 1000000),
MaxCombo = RNG.Next(1, 1000),
Rank = ScoreRank.XH,
- User = new User { Username = "TestUser" },
+ User = new APIUser { Username = "TestUser" },
};
importedScores.Add(scoreManager.Import(score).Result.Value);
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs
index 9fa5c83dba..ea3cfbd497 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs
@@ -6,9 +6,9 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Dashboard.Friends;
-using osu.Game.Users;
namespace osu.Game.Tests.Visual.UserInterface
{
@@ -29,17 +29,17 @@ namespace osu.Game.Tests.Visual.UserInterface
[Test]
public void Populate()
{
- AddStep("Populate", () => control.Populate(new List
+ AddStep("Populate", () => control.Populate(new List
{
- new User
+ new APIUser
{
IsOnline = true
},
- new User
+ new APIUser
{
IsOnline = false
},
- new User
+ new APIUser
{
IsOnline = false
}
diff --git a/osu.Game.Tournament.Tests/Components/TestSceneDrawableTournamentTeam.cs b/osu.Game.Tournament.Tests/Components/TestSceneDrawableTournamentTeam.cs
index 376c59ec2d..bb47683be1 100644
--- a/osu.Game.Tournament.Tests/Components/TestSceneDrawableTournamentTeam.cs
+++ b/osu.Game.Tournament.Tests/Components/TestSceneDrawableTournamentTeam.cs
@@ -3,13 +3,13 @@
using osu.Framework.Bindables;
using osu.Framework.Graphics;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Tests.Visual;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Models;
using osu.Game.Tournament.Screens.Drawings.Components;
using osu.Game.Tournament.Screens.Gameplay.Components;
using osu.Game.Tournament.Screens.Ladder.Components;
-using osu.Game.Users;
namespace osu.Game.Tournament.Tests.Components
{
@@ -24,13 +24,13 @@ namespace osu.Game.Tournament.Tests.Components
FullName = { Value = "Australia" },
Players =
{
- new User { Username = "ASecretBox" },
- new User { Username = "Dereban" },
- new User { Username = "mReKk" },
- new User { Username = "uyghti" },
- new User { Username = "Parkes" },
- new User { Username = "Shiroha" },
- new User { Username = "Jordan The Bear" },
+ new APIUser { Username = "ASecretBox" },
+ new APIUser { Username = "Dereban" },
+ new APIUser { Username = "mReKk" },
+ new APIUser { Username = "uyghti" },
+ new APIUser { Username = "Parkes" },
+ new APIUser { Username = "Shiroha" },
+ new APIUser { Username = "Jordan The Bear" },
}
};
diff --git a/osu.Game.Tournament.Tests/Components/TestSceneTournamentMatchChatDisplay.cs b/osu.Game.Tournament.Tests/Components/TestSceneTournamentMatchChatDisplay.cs
index 9905e17824..05989566c3 100644
--- a/osu.Game.Tournament.Tests/Components/TestSceneTournamentMatchChatDisplay.cs
+++ b/osu.Game.Tournament.Tests/Components/TestSceneTournamentMatchChatDisplay.cs
@@ -4,12 +4,12 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Chat;
using osu.Game.Tests.Visual;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.IPC;
using osu.Game.Tournament.Models;
-using osu.Game.Users;
namespace osu.Game.Tournament.Tests.Components
{
@@ -18,20 +18,20 @@ namespace osu.Game.Tournament.Tests.Components
private readonly Channel testChannel = new Channel();
private readonly Channel testChannel2 = new Channel();
- private readonly User admin = new User
+ private readonly APIUser admin = new APIUser
{
Username = "HappyStick",
Id = 2,
Colour = "f2ca34"
};
- private readonly User redUser = new User
+ private readonly APIUser redUser = new APIUser
{
Username = "BanchoBot",
Id = 3,
};
- private readonly User blueUser = new User
+ private readonly APIUser blueUser = new APIUser
{
Username = "Zallius",
Id = 4,
@@ -57,11 +57,11 @@ namespace osu.Game.Tournament.Tests.Components
{
Team1 =
{
- Value = new TournamentTeam { Players = new BindableList { redUser } }
+ Value = new TournamentTeam { Players = new BindableList { redUser } }
},
Team2 =
{
- Value = new TournamentTeam { Players = new BindableList { blueUser } }
+ Value = new TournamentTeam { Players = new BindableList { blueUser } }
}
};
diff --git a/osu.Game.Tournament.Tests/TournamentTestScene.cs b/osu.Game.Tournament.Tests/TournamentTestScene.cs
index 81741a43a9..8c05b4e915 100644
--- a/osu.Game.Tournament.Tests/TournamentTestScene.cs
+++ b/osu.Game.Tournament.Tests/TournamentTestScene.cs
@@ -14,6 +14,7 @@ using osu.Game.Tournament.IO;
using osu.Game.Tournament.IPC;
using osu.Game.Tournament.Models;
using osu.Game.Users;
+using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Tournament.Tests
{
@@ -120,11 +121,11 @@ namespace osu.Game.Tournament.Tests
},
Players =
{
- new User { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 12 } },
- new User { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 16 } },
- new User { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 20 } },
- new User { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 24 } },
- new User { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 30 } },
+ new APIUser { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 12 } },
+ new APIUser { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 16 } },
+ new APIUser { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 20 } },
+ new APIUser { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 24 } },
+ new APIUser { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 30 } },
}
}
},
@@ -137,11 +138,11 @@ namespace osu.Game.Tournament.Tests
FullName = { Value = "United States" },
Players =
{
- new User { Username = "Hello" },
- new User { Username = "Hello" },
- new User { Username = "Hello" },
- new User { Username = "Hello" },
- new User { Username = "Hello" },
+ new APIUser { Username = "Hello" },
+ new APIUser { Username = "Hello" },
+ new APIUser { Username = "Hello" },
+ new APIUser { Username = "Hello" },
+ new APIUser { Username = "Hello" },
}
}
},
diff --git a/osu.Game.Tournament/Components/DrawableTeamWithPlayers.cs b/osu.Game.Tournament/Components/DrawableTeamWithPlayers.cs
index e949bf9881..4d9afc23ac 100644
--- a/osu.Game.Tournament/Components/DrawableTeamWithPlayers.cs
+++ b/osu.Game.Tournament/Components/DrawableTeamWithPlayers.cs
@@ -5,8 +5,8 @@ using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Tournament.Models;
-using osu.Game.Users;
using osuTK;
using osuTK.Graphics;
@@ -54,7 +54,7 @@ namespace osu.Game.Tournament.Components
},
};
- TournamentSpriteText createPlayerText(User p) =>
+ TournamentSpriteText createPlayerText(APIUser p) =>
new TournamentSpriteText
{
Text = p.Username,
diff --git a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs
index f3550f7465..364cccd076 100644
--- a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs
+++ b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs
@@ -93,7 +93,7 @@ namespace osu.Game.Tournament.Components
},
new TournamentSpriteText
{
- Text = Beatmap.Metadata.Author,
+ Text = Beatmap.Metadata.Author.Username,
Padding = new MarginPadding { Right = 20 },
Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 14)
},
diff --git a/osu.Game.Tournament/Models/TournamentTeam.cs b/osu.Game.Tournament/Models/TournamentTeam.cs
index d895e4b538..24dee3b372 100644
--- a/osu.Game.Tournament/Models/TournamentTeam.cs
+++ b/osu.Game.Tournament/Models/TournamentTeam.cs
@@ -5,7 +5,7 @@ using System;
using System.Linq;
using Newtonsoft.Json;
using osu.Framework.Bindables;
-using osu.Game.Users;
+using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Tournament.Models
{
@@ -57,7 +57,7 @@ namespace osu.Game.Tournament.Models
};
[JsonProperty]
- public BindableList Players { get; set; } = new BindableList();
+ public BindableList Players { get; set; } = new BindableList();
public TournamentTeam()
{
diff --git a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs
index 0d2e64f300..6adddb5204 100644
--- a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs
@@ -13,6 +13,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Online.API;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Settings;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Models;
@@ -199,14 +200,14 @@ namespace osu.Game.Tournament.Screens.Editors
public void CreateNew()
{
- var user = new User();
+ var user = new APIUser();
team.Players.Add(user);
flow.Add(new PlayerRow(team, user));
}
public class PlayerRow : CompositeDrawable
{
- private readonly User user;
+ private readonly APIUser user;
[Resolved]
protected IAPIProvider API { get; private set; }
@@ -218,7 +219,7 @@ namespace osu.Game.Tournament.Screens.Editors
private readonly Container drawableContainer;
- public PlayerRow(TournamentTeam team, User user)
+ public PlayerRow(TournamentTeam team, APIUser user)
{
this.user = user;
diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs
index ee281466a2..d2f146c4c2 100644
--- a/osu.Game.Tournament/TournamentGameBase.cs
+++ b/osu.Game.Tournament/TournamentGameBase.cs
@@ -18,8 +18,8 @@ using osu.Game.Online.API.Requests.Responses;
using osu.Game.Tournament.IO;
using osu.Game.Tournament.IPC;
using osu.Game.Tournament.Models;
-using osu.Game.Users;
using osuTK.Input;
+using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
namespace osu.Game.Tournament
{
@@ -241,7 +241,7 @@ namespace osu.Game.Tournament
private void updateLoadProgressMessage(string s) => Schedule(() => initialisationText.Text = s);
- public void PopulateUser(User user, Action success = null, Action failure = null, bool immediate = false)
+ public void PopulateUser(APIUser user, Action success = null, Action failure = null, bool immediate = false)
{
var req = new GetUserRequest(user.Id, Ruleset.Value);
diff --git a/osu.Game/Audio/PreviewTrackManager.cs b/osu.Game/Audio/PreviewTrackManager.cs
index ca63add31d..fd9d5a97c6 100644
--- a/osu.Game/Audio/PreviewTrackManager.cs
+++ b/osu.Game/Audio/PreviewTrackManager.cs
@@ -1,13 +1,8 @@
// Copyright (c) ppy Pty Ltd . 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.IO;
-using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
-using osu.Framework.Audio.Mixing;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -19,27 +14,26 @@ namespace osu.Game.Audio
{
public class PreviewTrackManager : Component
{
+ private readonly IAdjustableAudioComponent mainTrackAdjustments;
+
private readonly BindableDouble muteBindable = new BindableDouble();
[Resolved]
private AudioManager audio { get; set; }
- private PreviewTrackStore trackStore;
+ private ITrackStore trackStore;
protected TrackManagerPreviewTrack CurrentTrack;
- private readonly BindableNumber globalTrackVolumeAdjust = new BindableNumber(OsuGameBase.GLOBAL_TRACK_VOLUME_ADJUST);
+ public PreviewTrackManager(IAdjustableAudioComponent mainTrackAdjustments)
+ {
+ this.mainTrackAdjustments = mainTrackAdjustments;
+ }
[BackgroundDependencyLoader]
private void load(AudioManager audioManager)
{
- // this is a temporary solution to get around muting ourselves.
- // todo: update this once we have a BackgroundTrackManager or similar.
- trackStore = new PreviewTrackStore(audioManager.TrackMixer, new OnlineStore());
-
- audio.AddItem(trackStore);
- trackStore.AddAdjustment(AdjustableProperty.Volume, globalTrackVolumeAdjust);
- trackStore.AddAdjustment(AdjustableProperty.Volume, audio.VolumeTrack);
+ trackStore = audioManager.GetTrackStore(new OnlineStore());
}
///
@@ -55,7 +49,7 @@ namespace osu.Game.Audio
{
CurrentTrack?.Stop();
CurrentTrack = track;
- audio.Tracks.AddAdjustment(AdjustableProperty.Volume, muteBindable);
+ mainTrackAdjustments.AddAdjustment(AdjustableProperty.Volume, muteBindable);
});
track.Stopped += () => Schedule(() =>
@@ -64,7 +58,7 @@ namespace osu.Game.Audio
return;
CurrentTrack = null;
- audio.Tracks.RemoveAdjustment(AdjustableProperty.Volume, muteBindable);
+ mainTrackAdjustments.RemoveAdjustment(AdjustableProperty.Volume, muteBindable);
});
return track;
@@ -116,52 +110,5 @@ namespace osu.Game.Audio
protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo.OnlineID}.mp3");
}
-
- private class PreviewTrackStore : AudioCollectionManager, ITrackStore
- {
- private readonly AudioMixer defaultMixer;
- private readonly IResourceStore store;
-
- internal PreviewTrackStore(AudioMixer defaultMixer, IResourceStore store)
- {
- this.defaultMixer = defaultMixer;
- this.store = store;
- }
-
- public Track GetVirtual(double length = double.PositiveInfinity)
- {
- if (IsDisposed) throw new ObjectDisposedException($"Cannot retrieve items for an already disposed {nameof(PreviewTrackStore)}");
-
- var track = new TrackVirtual(length);
- AddItem(track);
- return track;
- }
-
- public Track Get(string name)
- {
- if (IsDisposed) throw new ObjectDisposedException($"Cannot retrieve items for an already disposed {nameof(PreviewTrackStore)}");
-
- if (string.IsNullOrEmpty(name)) return null;
-
- var dataStream = store.GetStream(name);
-
- if (dataStream == null)
- return null;
-
- // Todo: This is quite unsafe. TrackBass shouldn't be exposed as public.
- Track track = new TrackBass(dataStream);
-
- defaultMixer.Add(track);
- AddItem(track);
-
- return track;
- }
-
- public Task
public static string GetDisplayTitle(this IBeatmapMetadataInfo metadataInfo)
{
- string author = string.IsNullOrEmpty(metadataInfo.Author) ? string.Empty : $"({metadataInfo.Author})";
+ string author = string.IsNullOrEmpty(metadataInfo.Author.Username) ? string.Empty : $"({metadataInfo.Author})";
return $"{metadataInfo.Artist} - {metadataInfo.Title} {author}".Trim();
}
@@ -36,7 +36,7 @@ namespace osu.Game.Beatmaps
///
public static RomanisableString GetDisplayTitleRomanisable(this IBeatmapMetadataInfo metadataInfo, bool includeCreator = true)
{
- string author = !includeCreator || string.IsNullOrEmpty(metadataInfo.Author) ? string.Empty : $"({metadataInfo.Author})";
+ string author = !includeCreator || string.IsNullOrEmpty(metadataInfo.Author.Username) ? string.Empty : $"({metadataInfo.Author})";
string artistUnicode = string.IsNullOrEmpty(metadataInfo.ArtistUnicode) ? metadataInfo.Artist : metadataInfo.ArtistUnicode;
string titleUnicode = string.IsNullOrEmpty(metadataInfo.TitleUnicode) ? metadataInfo.Title : metadataInfo.TitleUnicode;
diff --git a/osu.Game/Beatmaps/BeatmapModelManager.cs b/osu.Game/Beatmaps/BeatmapModelManager.cs
index f148d05aca..a654b05edb 100644
--- a/osu.Game/Beatmaps/BeatmapModelManager.cs
+++ b/osu.Game/Beatmaps/BeatmapModelManager.cs
@@ -11,7 +11,6 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using osu.Framework.Audio.Track;
-using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Textures;
using osu.Framework.Logging;
@@ -37,14 +36,12 @@ namespace osu.Game.Beatmaps
///
/// Fired when a single difficulty has been hidden.
///
- public IBindable> BeatmapHidden => beatmapHidden;
-
- private readonly Bindable> beatmapHidden = new Bindable>();
+ public event Action BeatmapHidden;
///
/// Fired when a single difficulty has been restored.
///
- public IBindable> BeatmapRestored => beatmapRestored;
+ public event Action BeatmapRestored;
///
/// An online lookup queue component which handles populating online beatmap metadata.
@@ -56,8 +53,6 @@ namespace osu.Game.Beatmaps
///
public IWorkingBeatmapCache WorkingBeatmapCache { private get; set; }
- private readonly Bindable> beatmapRestored = new Bindable>();
-
public override IEnumerable HandledExtensions => new[] { ".osz" };
protected override string[] HashableFileTypes => new[] { ".osu" };
@@ -75,8 +70,8 @@ namespace osu.Game.Beatmaps
this.rulesets = rulesets;
beatmaps = (BeatmapStore)ModelStore;
- beatmaps.BeatmapHidden += b => beatmapHidden.Value = new WeakReference(b);
- beatmaps.BeatmapRestored += b => beatmapRestored.Value = new WeakReference(b);
+ beatmaps.BeatmapHidden += b => BeatmapHidden?.Invoke(b);
+ beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b);
beatmaps.ItemRemoved += b => WorkingBeatmapCache?.Invalidate(b);
beatmaps.ItemUpdated += obj => WorkingBeatmapCache?.Invalidate(obj);
}
@@ -194,7 +189,11 @@ namespace osu.Game.Beatmaps
// Difficulty settings must be copied first due to the clone in `Beatmap<>.BeatmapInfo_Set`.
// This should hopefully be temporary, assuming said clone is eventually removed.
- beatmapInfo.BaseDifficulty.CopyFrom(beatmapContent.Difficulty);
+
+ // Warning: The directionality here is important. Changes have to be copied *from* beatmapContent (which comes from editor and is being saved)
+ // *to* the beatmapInfo (which is a database model and needs to receive values without the taiko slider velocity multiplier for correct operation).
+ // CopyTo() will undo such adjustments, while CopyFrom() will not.
+ beatmapContent.Difficulty.CopyTo(beatmapInfo.BaseDifficulty);
// All changes to metadata are made in the provided beatmapInfo, so this should be copied to the `IBeatmap` before encoding.
beatmapContent.BeatmapInfo = beatmapInfo;
diff --git a/osu.Game/Beatmaps/BeatmapSetHypeStatus.cs b/osu.Game/Beatmaps/BeatmapSetHypeStatus.cs
new file mode 100644
index 0000000000..8a576e396a
--- /dev/null
+++ b/osu.Game/Beatmaps/BeatmapSetHypeStatus.cs
@@ -0,0 +1,25 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using Newtonsoft.Json;
+
+namespace osu.Game.Beatmaps
+{
+ ///
+ /// Contains information about the current hype status of a beatmap set.
+ ///
+ public class BeatmapSetHypeStatus
+ {
+ ///
+ /// The current number of hypes that the set has received.
+ ///
+ [JsonProperty(@"current")]
+ public int Current { get; set; }
+
+ ///
+ /// The number of hypes required so that the set is eligible for nomination.
+ ///
+ [JsonProperty(@"required")]
+ public int Required { get; set; }
+ }
+}
diff --git a/osu.Game/Beatmaps/BeatmapSetNominationStatus.cs b/osu.Game/Beatmaps/BeatmapSetNominationStatus.cs
new file mode 100644
index 0000000000..6a19616a97
--- /dev/null
+++ b/osu.Game/Beatmaps/BeatmapSetNominationStatus.cs
@@ -0,0 +1,25 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using Newtonsoft.Json;
+
+namespace osu.Game.Beatmaps
+{
+ ///
+ /// Contains information about the current nomination status of a beatmap set.
+ ///
+ public class BeatmapSetNominationStatus
+ {
+ ///
+ /// The current number of nominations that the set has received.
+ ///
+ [JsonProperty(@"current")]
+ public int Current { get; set; }
+
+ ///
+ /// The number of nominations required so that the map is eligible for qualification.
+ ///
+ [JsonProperty(@"required")]
+ public int Required { get; set; }
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs
index 8136ebbd70..71376c28f1 100644
--- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs
+++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs
@@ -1,13 +1,17 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System.Collections.Generic;
using osu.Framework.Allocation;
+using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
+using osu.Game.Beatmaps.Drawables.Cards.Buttons;
+using osu.Game.Beatmaps.Drawables.Cards.Statistics;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
@@ -19,6 +23,7 @@ using osuTK;
using osu.Game.Overlays.BeatmapListing.Panels;
using osu.Game.Resources.Localisation.Web;
using osuTK.Graphics;
+using DownloadButton = osu.Game.Beatmaps.Drawables.Cards.Buttons.DownloadButton;
namespace osu.Game.Beatmaps.Drawables.Cards
{
@@ -31,15 +36,19 @@ namespace osu.Game.Beatmaps.Drawables.Cards
private const float corner_radius = 10;
private readonly APIBeatmapSet beatmapSet;
+ private readonly Bindable favouriteState;
private UpdateableOnlineBeatmapSetCover leftCover;
- private FillFlowContainer iconArea;
+ private FillFlowContainer leftIconArea;
+
+ private Container rightButtonArea;
private Container mainContent;
private BeatmapCardContentBackground mainContentBackground;
private GridContainer titleContainer;
private GridContainer artistContainer;
+ private FillFlowContainer statisticsContainer;
[Resolved]
private OverlayColourProvider colourProvider { get; set; }
@@ -48,6 +57,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
: base(HoverSampleSet.Submit)
{
this.beatmapSet = beatmapSet;
+ favouriteState = new Bindable(new BeatmapSetFavouriteState(beatmapSet.HasFavourited, beatmapSet.FavouriteCount));
}
[BackgroundDependencyLoader]
@@ -76,7 +86,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
RelativeSizeAxes = Axes.Both,
OnlineInfo = beatmapSet
},
- iconArea = new FillFlowContainer
+ leftIconArea = new FillFlowContainer
{
Margin = new MarginPadding(5),
AutoSizeAxes = Axes.Both,
@@ -85,6 +95,27 @@ namespace osu.Game.Beatmaps.Drawables.Cards
}
}
},
+ rightButtonArea = new Container
+ {
+ Name = @"Right (button) area",
+ Width = 30,
+ RelativeSizeAxes = Axes.Y,
+ Origin = Anchor.TopRight,
+ Anchor = Anchor.TopRight,
+ Child = new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Both,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Direction = FillDirection.Vertical,
+ Spacing = new Vector2(0, 14),
+ Children = new BeatmapCardIconButton[]
+ {
+ new FavouriteButton(beatmapSet) { Current = favouriteState },
+ new DownloadButton(beatmapSet)
+ }
+ }
+ },
mainContent = new Container
{
Name = @"Main content",
@@ -176,6 +207,15 @@ namespace osu.Game.Beatmaps.Drawables.Cards
d.AddText("mapped by ", t => t.Colour = colourProvider.Content2);
d.AddUserLink(beatmapSet.Author);
}),
+ statisticsContainer = new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(10, 0),
+ Alpha = 0,
+ ChildrenEnumerable = createStatistics()
+ }
}
},
new FillFlowContainer
@@ -214,10 +254,10 @@ namespace osu.Game.Beatmaps.Drawables.Cards
};
if (beatmapSet.HasVideo)
- iconArea.Add(new IconPill(FontAwesome.Solid.Film));
+ leftIconArea.Add(new IconPill(FontAwesome.Solid.Film));
if (beatmapSet.HasStoryboard)
- iconArea.Add(new IconPill(FontAwesome.Solid.Image));
+ leftIconArea.Add(new IconPill(FontAwesome.Solid.Image));
if (beatmapSet.HasExplicitContent)
{
@@ -265,6 +305,24 @@ namespace osu.Game.Beatmaps.Drawables.Cards
return BeatmapsetsStrings.ShowDetailsByArtist(romanisableArtist);
}
+ private IEnumerable createStatistics()
+ {
+ if (beatmapSet.HypeStatus != null)
+ yield return new HypesStatistic(beatmapSet.HypeStatus);
+
+ // web does not show nominations unless hypes are also present.
+ // see: https://github.com/ppy/osu-web/blob/8ed7d071fd1d3eaa7e43cf0e4ff55ca2fef9c07c/resources/assets/lib/beatmapset-panel.tsx#L443
+ if (beatmapSet.HypeStatus != null && beatmapSet.NominationStatus != null)
+ yield return new NominationsStatistic(beatmapSet.NominationStatus);
+
+ yield return new FavouritesStatistic(beatmapSet) { Current = favouriteState };
+ yield return new PlayCountStatistic(beatmapSet);
+
+ var dateStatistic = BeatmapCardDateStatistic.CreateFor(beatmapSet);
+ if (dateStatistic != null)
+ yield return dateStatistic;
+ }
+
private void updateState()
{
float targetWidth = width - height;
@@ -275,6 +333,8 @@ namespace osu.Game.Beatmaps.Drawables.Cards
mainContentBackground.Dimmed.Value = IsHovered;
leftCover.FadeColour(IsHovered ? OsuColour.Gray(0.2f) : Color4.White, TRANSITION_DURATION, Easing.OutQuint);
+ statisticsContainer.FadeTo(IsHovered ? 1 : 0, TRANSITION_DURATION, Easing.OutQuint);
+ rightButtonArea.FadeTo(IsHovered ? 1 : 0, TRANSITION_DURATION, Easing.OutQuint);
}
}
}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapSetFavouriteState.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapSetFavouriteState.cs
new file mode 100644
index 0000000000..82523cc865
--- /dev/null
+++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapSetFavouriteState.cs
@@ -0,0 +1,31 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Game.Beatmaps.Drawables.Cards.Buttons;
+using osu.Game.Beatmaps.Drawables.Cards.Statistics;
+
+namespace osu.Game.Beatmaps.Drawables.Cards
+{
+ ///
+ /// Stores the current favourite state of a beatmap set.
+ /// Used to coordinate between and .
+ ///
+ public readonly struct BeatmapSetFavouriteState
+ {
+ ///
+ /// Whether the currently logged-in user has favourited this beatmap.
+ ///
+ public bool Favourited { get; }
+
+ ///
+ /// The number of favourites that the beatmap set has received, including the currently logged-in user.
+ ///
+ public int FavouriteCount { get; }
+
+ public BeatmapSetFavouriteState(bool favourited, int favouriteCount)
+ {
+ Favourited = favourited;
+ FavouriteCount = favouriteCount;
+ }
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs
new file mode 100644
index 0000000000..155259d859
--- /dev/null
+++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs
@@ -0,0 +1,46 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Graphics.Containers;
+using osu.Game.Overlays;
+using osuTK;
+
+namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
+{
+ public abstract class BeatmapCardIconButton : OsuHoverContainer
+ {
+ protected readonly SpriteIcon Icon;
+
+ private float size;
+
+ public new float Size
+ {
+ get => size;
+ set
+ {
+ size = value;
+ Icon.Size = new Vector2(size);
+ }
+ }
+
+ protected BeatmapCardIconButton()
+ {
+ Add(Icon = new SpriteIcon());
+
+ AutoSizeAxes = Axes.Both;
+ Size = 12;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OverlayColourProvider colourProvider)
+ {
+ Anchor = Origin = Anchor.Centre;
+
+ IdleColour = colourProvider.Light1;
+ HoverColour = colourProvider.Content1;
+ }
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/DownloadButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/DownloadButton.cs
new file mode 100644
index 0000000000..00c0ccc3ce
--- /dev/null
+++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/DownloadButton.cs
@@ -0,0 +1,18 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Online.API.Requests.Responses;
+
+namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
+{
+ public class DownloadButton : BeatmapCardIconButton
+ {
+ public DownloadButton(APIBeatmapSet beatmapSet)
+ {
+ Icon.Icon = FontAwesome.Solid.FileDownload;
+ }
+
+ // TODO: implement behaviour
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/FavouriteButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/FavouriteButton.cs
new file mode 100644
index 0000000000..9fed2fde6f
--- /dev/null
+++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/FavouriteButton.cs
@@ -0,0 +1,86 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Bindables;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Graphics.UserInterface;
+using osu.Game.Online.API.Requests.Responses;
+using osu.Framework.Logging;
+using osu.Game.Online.API;
+using osu.Game.Online.API.Requests;
+using osu.Game.Resources.Localisation.Web;
+
+namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
+{
+ public class FavouriteButton : BeatmapCardIconButton, IHasCurrentValue
+ {
+ private readonly BindableWithCurrent current;
+
+ public Bindable Current
+ {
+ get => current.Current;
+ set => current.Current = value;
+ }
+
+ private readonly APIBeatmapSet beatmapSet;
+
+ private PostBeatmapFavouriteRequest favouriteRequest;
+
+ [Resolved]
+ private IAPIProvider api { get; set; }
+
+ public FavouriteButton(APIBeatmapSet beatmapSet)
+ {
+ current = new BindableWithCurrent(new BeatmapSetFavouriteState(beatmapSet.HasFavourited, beatmapSet.FavouriteCount));
+ this.beatmapSet = beatmapSet;
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ Action = toggleFavouriteStatus;
+ current.BindValueChanged(_ => updateState(), true);
+ }
+
+ private void toggleFavouriteStatus()
+ {
+ var actionType = current.Value.Favourited ? BeatmapFavouriteAction.UnFavourite : BeatmapFavouriteAction.Favourite;
+
+ favouriteRequest?.Cancel();
+ favouriteRequest = new PostBeatmapFavouriteRequest(beatmapSet.OnlineID, actionType);
+
+ Enabled.Value = false;
+ favouriteRequest.Success += () =>
+ {
+ bool favourited = actionType == BeatmapFavouriteAction.Favourite;
+
+ current.Value = new BeatmapSetFavouriteState(favourited, current.Value.FavouriteCount + (favourited ? 1 : -1));
+
+ Enabled.Value = true;
+ };
+ favouriteRequest.Failure += e =>
+ {
+ Logger.Error(e, $"Failed to {actionType.ToString().ToLower()} beatmap: {e.Message}");
+ Enabled.Value = true;
+ };
+
+ api.Queue(favouriteRequest);
+ }
+
+ private void updateState()
+ {
+ if (current.Value.Favourited)
+ {
+ Icon.Icon = FontAwesome.Solid.Heart;
+ TooltipText = BeatmapsetsStrings.ShowDetailsUnfavourite;
+ }
+ else
+ {
+ Icon.Icon = FontAwesome.Regular.Heart;
+ TooltipText = BeatmapsetsStrings.ShowDetailsFavourite;
+ }
+ }
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardDateStatistic.cs b/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardDateStatistic.cs
new file mode 100644
index 0000000000..8f2c4b538c
--- /dev/null
+++ b/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardDateStatistic.cs
@@ -0,0 +1,55 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+#nullable enable
+
+using System;
+using osu.Framework.Extensions.LocalisationExtensions;
+using osu.Framework.Graphics.Cursor;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Graphics;
+
+namespace osu.Game.Beatmaps.Drawables.Cards.Statistics
+{
+ public class BeatmapCardDateStatistic : BeatmapCardStatistic
+ {
+ private readonly DateTimeOffset dateTime;
+
+ private BeatmapCardDateStatistic(DateTimeOffset dateTime)
+ {
+ this.dateTime = dateTime;
+
+ Icon = FontAwesome.Regular.CheckCircle;
+ Text = dateTime.ToLocalisableString(@"d MMM yyyy");
+ }
+
+ public override object TooltipContent => dateTime;
+ public override ITooltip GetCustomTooltip() => new DateTooltip();
+
+ public static BeatmapCardDateStatistic? CreateFor(IBeatmapSetOnlineInfo beatmapSetInfo)
+ {
+ var displayDate = displayDateFor(beatmapSetInfo);
+
+ if (displayDate == null)
+ return null;
+
+ return new BeatmapCardDateStatistic(displayDate.Value);
+ }
+
+ private static DateTimeOffset? displayDateFor(IBeatmapSetOnlineInfo beatmapSetInfo)
+ {
+ // reference: https://github.com/ppy/osu-web/blob/ef432c11719fd1207bec5f9194b04f0033bdf02c/resources/assets/lib/beatmapset-panel.tsx#L36-L44
+ switch (beatmapSetInfo.Status)
+ {
+ case BeatmapSetOnlineStatus.Ranked:
+ case BeatmapSetOnlineStatus.Approved:
+ case BeatmapSetOnlineStatus.Loved:
+ case BeatmapSetOnlineStatus.Qualified:
+ return beatmapSetInfo.Ranked;
+
+ default:
+ return beatmapSetInfo.LastUpdated;
+ }
+ }
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardStatistic.cs b/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardStatistic.cs
new file mode 100644
index 0000000000..f46926284f
--- /dev/null
+++ b/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardStatistic.cs
@@ -0,0 +1,80 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Cursor;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Localisation;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Overlays;
+using osuTK;
+
+namespace osu.Game.Beatmaps.Drawables.Cards.Statistics
+{
+ ///
+ /// A single statistic shown on a beatmap card.
+ ///
+ public abstract class BeatmapCardStatistic : CompositeDrawable, IHasTooltip, IHasCustomTooltip
+ {
+ protected IconUsage Icon
+ {
+ get => spriteIcon.Icon;
+ set => spriteIcon.Icon = value;
+ }
+
+ protected LocalisableString Text
+ {
+ get => spriteText.Text;
+ set => spriteText.Text = value;
+ }
+
+ public LocalisableString TooltipText { get; protected set; }
+
+ private readonly SpriteIcon spriteIcon;
+ private readonly OsuSpriteText spriteText;
+
+ protected BeatmapCardStatistic()
+ {
+ AutoSizeAxes = Axes.Both;
+
+ InternalChild = new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(5, 0),
+ Children = new Drawable[]
+ {
+ spriteIcon = new SpriteIcon
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ Size = new Vector2(10),
+ Margin = new MarginPadding { Top = 1 }
+ },
+ spriteText = new OsuSpriteText
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ Font = OsuFont.Default.With(size: 14)
+ }
+ }
+ };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OverlayColourProvider colourProvider)
+ {
+ spriteIcon.Colour = colourProvider.Content2;
+ }
+
+ #region Tooltip implementation
+
+ public virtual ITooltip GetCustomTooltip() => null;
+ public virtual object TooltipContent => null;
+
+ #endregion
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/Statistics/FavouritesStatistic.cs b/osu.Game/Beatmaps/Drawables/Cards/Statistics/FavouritesStatistic.cs
new file mode 100644
index 0000000000..d924fd938b
--- /dev/null
+++ b/osu.Game/Beatmaps/Drawables/Cards/Statistics/FavouritesStatistic.cs
@@ -0,0 +1,44 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using Humanizer;
+using osu.Framework.Bindables;
+using osu.Framework.Extensions.LocalisationExtensions;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Graphics.UserInterface;
+using osu.Game.Resources.Localisation.Web;
+
+namespace osu.Game.Beatmaps.Drawables.Cards.Statistics
+{
+ ///
+ /// Shows the number of favourites that a beatmap set has received.
+ ///
+ public class FavouritesStatistic : BeatmapCardStatistic, IHasCurrentValue
+ {
+ private readonly BindableWithCurrent current;
+
+ public Bindable Current
+ {
+ get => current.Current;
+ set => current.Current = value;
+ }
+
+ public FavouritesStatistic(IBeatmapSetOnlineInfo onlineInfo)
+ {
+ current = new BindableWithCurrent(new BeatmapSetFavouriteState(onlineInfo.HasFavourited, onlineInfo.FavouriteCount));
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+ current.BindValueChanged(_ => updateState(), true);
+ }
+
+ private void updateState()
+ {
+ Icon = current.Value.Favourited ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart;
+ Text = current.Value.FavouriteCount.ToMetric(decimals: 1);
+ TooltipText = BeatmapsStrings.PanelFavourites(current.Value.FavouriteCount.ToLocalisableString(@"N0"));
+ }
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/Statistics/HypesStatistic.cs b/osu.Game/Beatmaps/Drawables/Cards/Statistics/HypesStatistic.cs
new file mode 100644
index 0000000000..3fe31c7a41
--- /dev/null
+++ b/osu.Game/Beatmaps/Drawables/Cards/Statistics/HypesStatistic.cs
@@ -0,0 +1,22 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Extensions.LocalisationExtensions;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Resources.Localisation.Web;
+
+namespace osu.Game.Beatmaps.Drawables.Cards.Statistics
+{
+ ///
+ /// Shows the number of current hypes that a map has received, as well as the number of hypes required for nomination.
+ ///
+ public class HypesStatistic : BeatmapCardStatistic
+ {
+ public HypesStatistic(BeatmapSetHypeStatus hypeStatus)
+ {
+ Icon = FontAwesome.Solid.Bullhorn;
+ Text = hypeStatus.Current.ToLocalisableString();
+ TooltipText = BeatmapsStrings.HypeRequiredText(hypeStatus.Current.ToLocalisableString(), hypeStatus.Required.ToLocalisableString());
+ }
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/Statistics/NominationsStatistic.cs b/osu.Game/Beatmaps/Drawables/Cards/Statistics/NominationsStatistic.cs
new file mode 100644
index 0000000000..f09269a615
--- /dev/null
+++ b/osu.Game/Beatmaps/Drawables/Cards/Statistics/NominationsStatistic.cs
@@ -0,0 +1,22 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Extensions.LocalisationExtensions;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Resources.Localisation.Web;
+
+namespace osu.Game.Beatmaps.Drawables.Cards.Statistics
+{
+ ///
+ /// Shows the number of current nominations that a map has received, as well as the number of nominations required for qualification.
+ ///
+ public class NominationsStatistic : BeatmapCardStatistic
+ {
+ public NominationsStatistic(BeatmapSetNominationStatus nominationStatus)
+ {
+ Icon = FontAwesome.Solid.ThumbsUp;
+ Text = nominationStatus.Current.ToLocalisableString();
+ TooltipText = BeatmapsStrings.NominationsRequiredText(nominationStatus.Current.ToLocalisableString(), nominationStatus.Required.ToLocalisableString());
+ }
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/Statistics/PlayCountStatistic.cs b/osu.Game/Beatmaps/Drawables/Cards/Statistics/PlayCountStatistic.cs
new file mode 100644
index 0000000000..d8f0c36bd9
--- /dev/null
+++ b/osu.Game/Beatmaps/Drawables/Cards/Statistics/PlayCountStatistic.cs
@@ -0,0 +1,23 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using Humanizer;
+using osu.Framework.Extensions.LocalisationExtensions;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Resources.Localisation.Web;
+
+namespace osu.Game.Beatmaps.Drawables.Cards.Statistics
+{
+ ///
+ /// Shows the number of times the given beatmap set has been played.
+ ///
+ public class PlayCountStatistic : BeatmapCardStatistic
+ {
+ public PlayCountStatistic(IBeatmapSetOnlineInfo onlineInfo)
+ {
+ Icon = FontAwesome.Regular.PlayCircle;
+ Text = onlineInfo.PlayCount.ToMetric(decimals: 1);
+ TooltipText = BeatmapsStrings.PanelPlaycount(onlineInfo.PlayCount.ToLocalisableString(@"N0"));
+ }
+ }
+}
diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs
index 3ed5055b7f..9117da5d32 100644
--- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs
+++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs
@@ -129,7 +129,7 @@ namespace osu.Game.Beatmaps.Formats
if (!string.IsNullOrEmpty(beatmap.Metadata.TitleUnicode)) writer.WriteLine(FormattableString.Invariant($"TitleUnicode: {beatmap.Metadata.TitleUnicode}"));
writer.WriteLine(FormattableString.Invariant($"Artist: {beatmap.Metadata.Artist}"));
if (!string.IsNullOrEmpty(beatmap.Metadata.ArtistUnicode)) writer.WriteLine(FormattableString.Invariant($"ArtistUnicode: {beatmap.Metadata.ArtistUnicode}"));
- writer.WriteLine(FormattableString.Invariant($"Creator: {beatmap.Metadata.AuthorString}"));
+ writer.WriteLine(FormattableString.Invariant($"Creator: {beatmap.Metadata.Author.Username}"));
writer.WriteLine(FormattableString.Invariant($"Version: {beatmap.BeatmapInfo.Version}"));
if (!string.IsNullOrEmpty(beatmap.Metadata.Source)) writer.WriteLine(FormattableString.Invariant($"Source: {beatmap.Metadata.Source}"));
if (!string.IsNullOrEmpty(beatmap.Metadata.Tags)) writer.WriteLine(FormattableString.Invariant($"Tags: {beatmap.Metadata.Tags}"));
diff --git a/osu.Game/Beatmaps/IBeatmapMetadataInfo.cs b/osu.Game/Beatmaps/IBeatmapMetadataInfo.cs
index 55aee7d7bc..968ad14928 100644
--- a/osu.Game/Beatmaps/IBeatmapMetadataInfo.cs
+++ b/osu.Game/Beatmaps/IBeatmapMetadataInfo.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using osu.Game.Users;
#nullable enable
@@ -35,7 +36,7 @@ namespace osu.Game.Beatmaps
///
/// The author of this beatmap.
///
- string Author { get; } // eventually should be linked to a persisted User.
+ IUser Author { get; }
///
/// The source of this beatmap.
diff --git a/osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs
index 6def6ec21d..2982cf9c3a 100644
--- a/osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs
+++ b/osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs
@@ -102,5 +102,19 @@ namespace osu.Game.Beatmaps
/// Total vote counts of user ratings on a scale of 0..10 where 0 is unused (probably will be fixed at API?).
///
int[]? Ratings { get; }
+
+ ///
+ /// Contains the current hype status of the beatmap set.
+ /// Non-null only for , , and sets.
+ ///
+ ///
+ /// See: https://github.com/ppy/osu-web/blob/93930cd02cfbd49724929912597c727c9fbadcd1/app/Models/Beatmapset.php#L155
+ ///
+ BeatmapSetHypeStatus? HypeStatus { get; }
+
+ ///
+ /// Contains the current nomination status of the beatmap set.
+ ///
+ BeatmapSetNominationStatus? NominationStatus { get; }
}
}
diff --git a/osu.Game/Beatmaps/WorkingBeatmapCache.cs b/osu.Game/Beatmaps/WorkingBeatmapCache.cs
index 11257e3abc..0af28902a0 100644
--- a/osu.Game/Beatmaps/WorkingBeatmapCache.cs
+++ b/osu.Game/Beatmaps/WorkingBeatmapCache.cs
@@ -41,7 +41,7 @@ namespace osu.Game.Beatmaps
[CanBeNull]
private readonly GameHost host;
- public WorkingBeatmapCache([NotNull] AudioManager audioManager, IResourceStore resources, IResourceStore files, WorkingBeatmap defaultBeatmap = null, GameHost host = null)
+ public WorkingBeatmapCache(ITrackStore trackStore, AudioManager audioManager, IResourceStore resources, IResourceStore files, WorkingBeatmap defaultBeatmap = null, GameHost host = null)
{
DefaultBeatmap = defaultBeatmap;
@@ -50,7 +50,7 @@ namespace osu.Game.Beatmaps
this.host = host;
this.files = files;
largeTextureStore = new LargeTextureStore(host?.CreateTextureLoaderStore(files));
- trackStore = audioManager.GetTrackStore(files);
+ this.trackStore = trackStore;
}
public void Invalidate(BeatmapSetInfo info)
diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs
index d2f9ee1dc1..019749760f 100644
--- a/osu.Game/Database/ArchiveModelManager.cs
+++ b/osu.Game/Database/ArchiveModelManager.cs
@@ -10,7 +10,6 @@ using System.Threading.Tasks;
using Humanizer;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
-using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Logging;
@@ -63,17 +62,13 @@ namespace osu.Game.Database
/// Fired when a new or updated becomes available in the database.
/// This is not guaranteed to run on the update thread.
///
- public IBindable> ItemUpdated => itemUpdated;
-
- private readonly Bindable> itemUpdated = new Bindable>();
+ public event Action ItemUpdated;
///
/// Fired when a is removed from the database.
/// This is not guaranteed to run on the update thread.
///
- public IBindable> ItemRemoved => itemRemoved;
-
- private readonly Bindable> itemRemoved = new Bindable>();
+ public event Action ItemRemoved;
public virtual IEnumerable HandledExtensions => new[] { @".zip" };
@@ -93,8 +88,8 @@ namespace osu.Game.Database
ContextFactory = contextFactory;
ModelStore = modelStore;
- ModelStore.ItemUpdated += item => handleEvent(() => itemUpdated.Value = new WeakReference(item));
- ModelStore.ItemRemoved += item => handleEvent(() => itemRemoved.Value = new WeakReference(item));
+ ModelStore.ItemUpdated += item => handleEvent(() => ItemUpdated?.Invoke(item));
+ ModelStore.ItemRemoved += item => handleEvent(() => ItemRemoved?.Invoke(item));
exportStorage = storage.GetStorageForDirectory(@"exports");
diff --git a/osu.Game/Database/IModelDownloader.cs b/osu.Game/Database/IModelDownloader.cs
index 3c57a277ba..81fba14244 100644
--- a/osu.Game/Database/IModelDownloader.cs
+++ b/osu.Game/Database/IModelDownloader.cs
@@ -3,7 +3,6 @@
using System;
using osu.Game.Online.API;
-using osu.Framework.Bindables;
namespace osu.Game.Database
{
@@ -18,13 +17,13 @@ namespace osu.Game.Database
/// Fired when a download begins.
/// This is NOT run on the update thread and should be scheduled.
///
- IBindable>> DownloadBegan { get; }
+ event Action> DownloadBegan;
///
/// Fired when a download is interrupted, either due to user cancellation or failure.
/// This is NOT run on the update thread and should be scheduled.
///
- IBindable>> DownloadFailed { get; }
+ event Action> DownloadFailed;
///
/// Begin a download for the requested .
diff --git a/osu.Game/Database/IModelManager.cs b/osu.Game/Database/IModelManager.cs
index 0be927322d..15ad455f21 100644
--- a/osu.Game/Database/IModelManager.cs
+++ b/osu.Game/Database/IModelManager.cs
@@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
-using osu.Framework.Bindables;
using osu.Game.IO;
namespace osu.Game.Database
@@ -18,16 +17,14 @@ namespace osu.Game.Database
where TModel : class
{
///
- /// A bindable which contains a weak reference to the last item that was updated.
- /// This is not thread-safe and should be scheduled locally if consumed from a drawable component.
+ /// Fired when an item is updated.
///
- IBindable> ItemUpdated { get; }
+ event Action ItemUpdated;
///
- /// A bindable which contains a weak reference to the last item that was removed.
- /// This is not thread-safe and should be scheduled locally if consumed from a drawable component.
+ /// Fired when an item is removed.
///
- IBindable> ItemRemoved { get; }
+ event Action ItemRemoved;
///
/// This is a temporary method and will likely be replaced by a full-fledged (and more correctly placed) migration process in the future.
diff --git a/osu.Game/Database/ModelDownloader.cs b/osu.Game/Database/ModelDownloader.cs
index e44ae21ed6..3c1f181f24 100644
--- a/osu.Game/Database/ModelDownloader.cs
+++ b/osu.Game/Database/ModelDownloader.cs
@@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Humanizer;
-using osu.Framework.Bindables;
using osu.Framework.Logging;
using osu.Framework.Platform;
using osu.Game.Online.API;
@@ -20,13 +19,9 @@ namespace osu.Game.Database
{
public Action PostNotification { protected get; set; }
- public IBindable>> DownloadBegan => downloadBegan;
+ public event Action> DownloadBegan;
- private readonly Bindable>> downloadBegan = new Bindable>>();
-
- public IBindable>> DownloadFailed => downloadFailed;
-
- private readonly Bindable>> downloadFailed = new Bindable>>();
+ public event Action> DownloadFailed;
private readonly IModelImporter importer;
private readonly IAPIProvider api;
@@ -73,7 +68,7 @@ namespace osu.Game.Database
// for now a failed import will be marked as a failed download for simplicity.
if (!imported.Any())
- downloadFailed.Value = new WeakReference>(request);
+ DownloadFailed?.Invoke(request);
CurrentDownloads.Remove(request);
}, TaskCreationOptions.LongRunning);
@@ -92,14 +87,14 @@ namespace osu.Game.Database
api.PerformAsync(request);
- downloadBegan.Value = new WeakReference>(request);
+ DownloadBegan?.Invoke(request);
return true;
void triggerFailure(Exception error)
{
CurrentDownloads.Remove(request);
- downloadFailed.Value = new WeakReference>(request);
+ DownloadFailed?.Invoke(request);
notification.State = ProgressNotificationState.Cancelled;
diff --git a/osu.Game/Database/RealmContextFactory.cs b/osu.Game/Database/RealmContextFactory.cs
index 85f7dd6b89..42ae986921 100644
--- a/osu.Game/Database/RealmContextFactory.cs
+++ b/osu.Game/Database/RealmContextFactory.cs
@@ -3,6 +3,7 @@
using System;
using System.Linq;
+using System.Reflection;
using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Development;
@@ -35,8 +36,9 @@ namespace osu.Game.Database
/// 6 First tracked version (~20211018)
/// 7 Changed OnlineID fields to non-nullable to add indexing support (20211018)
/// 8 Rebind scroll adjust keys to not have control modifier (20211029)
+ /// 9 Converted BeatmapMetadata.Author from string to RealmUser (20211104)
///
- private const int schema_version = 8;
+ private const int schema_version = 9;
///
/// Lock object which is held during sections, blocking context creation during blocking periods.
@@ -151,50 +153,86 @@ namespace osu.Game.Database
private void onMigration(Migration migration, ulong lastSchemaVersion)
{
- if (lastSchemaVersion < 8)
+ for (ulong i = lastSchemaVersion; i <= schema_version; i++)
+ applyMigrationsForVersion(migration, i);
+ }
+
+ private void applyMigrationsForVersion(Migration migration, ulong version)
+ {
+ switch (version)
{
- // Ctrl -/+ now adjusts UI scale so let's clear any bindings which overlap these combinations.
- // New defaults will be populated by the key store afterwards.
- var keyBindings = migration.NewRealm.All();
+ case 7:
+ convertOnlineIDs();
+ convertOnlineIDs();
+ convertOnlineIDs();
- var increaseSpeedBinding = keyBindings.FirstOrDefault(k => k.ActionInt == (int)GlobalAction.IncreaseScrollSpeed);
- if (increaseSpeedBinding != null && increaseSpeedBinding.KeyCombination.Keys.SequenceEqual(new[] { InputKey.Control, InputKey.Plus }))
- migration.NewRealm.Remove(increaseSpeedBinding);
+ void convertOnlineIDs() where T : RealmObject
+ {
+ string className = getMappedOrOriginalName(typeof(T));
- var decreaseSpeedBinding = keyBindings.FirstOrDefault(k => k.ActionInt == (int)GlobalAction.DecreaseScrollSpeed);
- if (decreaseSpeedBinding != null && decreaseSpeedBinding.KeyCombination.Keys.SequenceEqual(new[] { InputKey.Control, InputKey.Minus }))
- migration.NewRealm.Remove(decreaseSpeedBinding);
- }
+ // version was not bumped when the beatmap/ruleset models were added
+ // therefore we must manually check for their presence to avoid throwing on the `DynamicApi` calls.
+ if (!migration.OldRealm.Schema.TryFindObjectSchema(className, out _))
+ return;
- if (lastSchemaVersion < 7)
- {
- convertOnlineIDs();
- convertOnlineIDs();
- convertOnlineIDs();
+ var oldItems = migration.OldRealm.DynamicApi.All(className);
+ var newItems = migration.NewRealm.DynamicApi.All(className);
- void convertOnlineIDs() where T : RealmObject
- {
- string className = typeof(T).Name.Replace(@"Realm", string.Empty);
+ int itemCount = newItems.Count();
- // version was not bumped when the beatmap/ruleset models were added
- // therefore we must manually check for their presence to avoid throwing on the `DynamicApi` calls.
- if (!migration.OldRealm.Schema.TryFindObjectSchema(className, out _))
+ for (int i = 0; i < itemCount; i++)
+ {
+ dynamic? oldItem = oldItems.ElementAt(i);
+ dynamic? newItem = newItems.ElementAt(i);
+
+ long? nullableOnlineID = oldItem?.OnlineID;
+ newItem.OnlineID = (int)(nullableOnlineID ?? -1);
+ }
+ }
+
+ break;
+
+ case 8:
+ // Ctrl -/+ now adjusts UI scale so let's clear any bindings which overlap these combinations.
+ // New defaults will be populated by the key store afterwards.
+ var keyBindings = migration.NewRealm.All();
+
+ var increaseSpeedBinding = keyBindings.FirstOrDefault(k => k.ActionInt == (int)GlobalAction.IncreaseScrollSpeed);
+ if (increaseSpeedBinding != null && increaseSpeedBinding.KeyCombination.Keys.SequenceEqual(new[] { InputKey.Control, InputKey.Plus }))
+ migration.NewRealm.Remove(increaseSpeedBinding);
+
+ var decreaseSpeedBinding = keyBindings.FirstOrDefault(k => k.ActionInt == (int)GlobalAction.DecreaseScrollSpeed);
+ if (decreaseSpeedBinding != null && decreaseSpeedBinding.KeyCombination.Keys.SequenceEqual(new[] { InputKey.Control, InputKey.Minus }))
+ migration.NewRealm.Remove(decreaseSpeedBinding);
+
+ break;
+
+ case 9:
+ // Pretty pointless to do this as beatmaps aren't really loaded via realm yet, but oh well.
+ string metadataClassName = getMappedOrOriginalName(typeof(RealmBeatmapMetadata));
+
+ // May be coming from a version before `RealmBeatmapMetadata` existed.
+ if (!migration.OldRealm.Schema.TryFindObjectSchema(metadataClassName, out _))
return;
- var oldItems = migration.OldRealm.DynamicApi.All(className);
- var newItems = migration.NewRealm.DynamicApi.All(className);
+ var oldMetadata = migration.OldRealm.DynamicApi.All(metadataClassName);
+ var newMetadata = migration.NewRealm.All();
- int itemCount = newItems.Count();
+ int metadataCount = newMetadata.Count();
- for (int i = 0; i < itemCount; i++)
+ for (int i = 0; i < metadataCount; i++)
{
- dynamic? oldItem = oldItems.ElementAt(i);
- dynamic? newItem = newItems.ElementAt(i);
+ dynamic? oldItem = oldMetadata.ElementAt(i);
+ var newItem = newMetadata.ElementAt(i);
- long? nullableOnlineID = oldItem?.OnlineID;
- newItem.OnlineID = (int)(nullableOnlineID ?? -1);
+ string username = oldItem.Author;
+ newItem.Author = new RealmUser
+ {
+ Username = username
+ };
}
- }
+
+ break;
}
}
@@ -252,6 +290,9 @@ namespace osu.Game.Database
});
}
+ // https://github.com/realm/realm-dotnet/blob/32f4ebcc88b3e80a3b254412665340cd9f3bd6b5/Realm/Realm/Extensions/ReflectionExtensions.cs#L46
+ private static string getMappedOrOriginalName(MemberInfo member) => member.GetCustomAttribute()?.Mapping ?? member.Name;
+
private bool isDisposed;
public void Dispose()
diff --git a/osu.Game/Database/UserLookupCache.cs b/osu.Game/Database/UserLookupCache.cs
index 3626f5e83a..dae2d2549c 100644
--- a/osu.Game/Database/UserLookupCache.cs
+++ b/osu.Game/Database/UserLookupCache.cs
@@ -9,33 +9,33 @@ using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
-using osu.Game.Users;
+using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Database
{
- public class UserLookupCache : MemoryCachingComponent
+ public class UserLookupCache : MemoryCachingComponent
{
[Resolved]
private IAPIProvider api { get; set; }
///
- /// Perform an API lookup on the specified user, populating a model.
+ /// Perform an API lookup on the specified user, populating a model.
///
/// The user to lookup.
/// An optional cancellation token.
/// The populated user, or null if the user does not exist or the request could not be satisfied.
[ItemCanBeNull]
- public Task GetUserAsync(int userId, CancellationToken token = default) => GetAsync(userId, token);
+ public Task GetUserAsync(int userId, CancellationToken token = default) => GetAsync(userId, token);
///
- /// Perform an API lookup on the specified users, populating a model.
+ /// Perform an API lookup on the specified users, populating a model.
///
/// The users to lookup.
/// An optional cancellation token.
/// The populated users. May include null results for failed retrievals.
- public Task GetUsersAsync(int[] userIds, CancellationToken token = default)
+ public Task GetUsersAsync(int[] userIds, CancellationToken token = default)
{
- var userLookupTasks = new List>();
+ var userLookupTasks = new List>();
foreach (int u in userIds)
{
@@ -51,18 +51,18 @@ namespace osu.Game.Database
return Task.WhenAll(userLookupTasks);
}
- protected override async Task ComputeValueAsync(int lookup, CancellationToken token = default)
+ protected override async Task ComputeValueAsync(int lookup, CancellationToken token = default)
=> await queryUser(lookup).ConfigureAwait(false);
- private readonly Queue<(int id, TaskCompletionSource)> pendingUserTasks = new Queue<(int, TaskCompletionSource)>();
+ private readonly Queue<(int id, TaskCompletionSource)> pendingUserTasks = new Queue<(int, TaskCompletionSource)>();
private Task pendingRequestTask;
private readonly object taskAssignmentLock = new object();
- private Task queryUser(int userId)
+ private Task queryUser(int userId)
{
lock (taskAssignmentLock)
{
- var tcs = new TaskCompletionSource();
+ var tcs = new TaskCompletionSource();
// Add to the queue.
pendingUserTasks.Enqueue((userId, tcs));
@@ -78,14 +78,14 @@ namespace osu.Game.Database
private void performLookup()
{
// contains at most 50 unique user IDs from userTasks, which is used to perform the lookup.
- var userTasks = new Dictionary>>();
+ var userTasks = new Dictionary>>();
// Grab at most 50 unique user IDs from the queue.
lock (taskAssignmentLock)
{
while (pendingUserTasks.Count > 0 && userTasks.Count < 50)
{
- (int id, TaskCompletionSource task) next = pendingUserTasks.Dequeue();
+ (int id, TaskCompletionSource task) next = pendingUserTasks.Dequeue();
// Perform a secondary check for existence, in case the user was queried in a previous batch.
if (CheckExists(next.id, out var existing))
@@ -95,7 +95,7 @@ namespace osu.Game.Database
if (userTasks.TryGetValue(next.id, out var tasks))
tasks.Add(next.task);
else
- userTasks[next.id] = new List> { next.task };
+ userTasks[next.id] = new List> { next.task };
}
}
}
@@ -115,7 +115,7 @@ namespace osu.Game.Database
createNewTask();
}
- List foundUsers = request.Response?.Users;
+ List foundUsers = request.Response?.Users;
if (foundUsers != null)
{
diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs
index 7d1210d0e3..1d286d3487 100644
--- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs
+++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs
@@ -46,7 +46,7 @@ namespace osu.Game.Graphics.Containers
AddText(text[previousLinkEnd..link.Index]);
string displayText = text.Substring(link.Index, link.Length);
- string linkArgument = link.Argument;
+ object linkArgument = link.Argument;
string tooltip = displayText == link.Url ? null : link.Url;
AddLink(displayText, link.Action, linkArgument, tooltip);
@@ -62,16 +62,16 @@ namespace osu.Game.Graphics.Containers
public void AddLink(LocalisableString text, Action action, string tooltipText = null, Action creationParameters = null)
=> createLink(CreateChunkFor(text, true, CreateSpriteText, creationParameters), new LinkDetails(LinkAction.Custom, string.Empty), tooltipText, action);
- public void AddLink(LocalisableString text, LinkAction action, string argument, string tooltipText = null, Action creationParameters = null)
+ public void AddLink(LocalisableString text, LinkAction action, object argument, string tooltipText = null, Action creationParameters = null)
=> createLink(CreateChunkFor(text, true, CreateSpriteText, creationParameters), new LinkDetails(action, argument), tooltipText);
- public void AddLink(IEnumerable text, LinkAction action, string linkArgument, string tooltipText = null)
+ public void AddLink(IEnumerable text, LinkAction action, object linkArgument, string tooltipText = null)
{
createLink(new TextPartManual(text), new LinkDetails(action, linkArgument), tooltipText);
}
- public void AddUserLink(User user, Action creationParameters = null)
- => createLink(CreateChunkFor(user.Username, true, CreateSpriteText, creationParameters), new LinkDetails(LinkAction.OpenUserProfile, user.Id.ToString()), "view profile");
+ public void AddUserLink(IUser user, Action creationParameters = null)
+ => createLink(CreateChunkFor(user.Username, true, CreateSpriteText, creationParameters), new LinkDetails(LinkAction.OpenUserProfile, user), "view profile");
private void createLink(ITextPart textPart, LinkDetails link, LocalisableString tooltipText, Action action = null)
{
@@ -83,7 +83,7 @@ namespace osu.Game.Graphics.Containers
game.HandleLink(link);
// fallback to handle cases where OsuGame is not available, ie. tournament client.
else if (link.Action == LinkAction.External)
- host.OpenUrlExternally(link.Argument);
+ host.OpenUrlExternally(link.Argument.ToString());
};
AddPart(new TextLink(textPart, tooltipText, onClickAction));
diff --git a/osu.Game/Input/RealmKeyBindingStore.cs b/osu.Game/Input/RealmKeyBindingStore.cs
index c65e36e478..046969579c 100644
--- a/osu.Game/Input/RealmKeyBindingStore.cs
+++ b/osu.Game/Input/RealmKeyBindingStore.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
+using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Game.Database;
using osu.Game.Input.Bindings;
@@ -16,10 +17,12 @@ namespace osu.Game.Input
public class RealmKeyBindingStore
{
private readonly RealmContextFactory realmFactory;
+ private readonly ReadableKeyCombinationProvider keyCombinationProvider;
- public RealmKeyBindingStore(RealmContextFactory realmFactory)
+ public RealmKeyBindingStore(RealmContextFactory realmFactory, ReadableKeyCombinationProvider keyCombinationProvider)
{
this.realmFactory = realmFactory;
+ this.keyCombinationProvider = keyCombinationProvider;
}
///
@@ -35,7 +38,7 @@ namespace osu.Game.Input
{
foreach (var action in context.All().Where(b => b.RulesetID == null && (GlobalAction)b.ActionInt == globalAction))
{
- string str = action.KeyCombination.ReadableString();
+ string str = keyCombinationProvider.GetReadableString(action.KeyCombination);
// even if found, the readable string may be empty for an unbound action.
if (str.Length > 0)
diff --git a/osu.Game/Models/RealmBeatmapMetadata.cs b/osu.Game/Models/RealmBeatmapMetadata.cs
index 6ea7170d0f..db1b09e6ad 100644
--- a/osu.Game/Models/RealmBeatmapMetadata.cs
+++ b/osu.Game/Models/RealmBeatmapMetadata.cs
@@ -5,6 +5,7 @@ using System;
using Newtonsoft.Json;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
+using osu.Game.Users;
using Realms;
#nullable enable
@@ -26,7 +27,7 @@ namespace osu.Game.Models
[JsonProperty("artist_unicode")]
public string ArtistUnicode { get; set; } = string.Empty;
- public string Author { get; set; } = string.Empty; // eventually should be linked to a persisted User.
+ public RealmUser Author { get; set; } = new RealmUser();
public string Source { get; set; } = string.Empty;
@@ -41,5 +42,7 @@ namespace osu.Game.Models
public string AudioFile { get; set; } = string.Empty;
public string BackgroundFile { get; set; } = string.Empty;
+
+ IUser IBeatmapMetadataInfo.Author => Author;
}
}
diff --git a/osu.Game/Models/RealmUser.cs b/osu.Game/Models/RealmUser.cs
new file mode 100644
index 0000000000..154ece502f
--- /dev/null
+++ b/osu.Game/Models/RealmUser.cs
@@ -0,0 +1,17 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Game.Users;
+using Realms;
+
+namespace osu.Game.Models
+{
+ public class RealmUser : EmbeddedObject, IUser
+ {
+ public int OnlineID { get; set; } = 1;
+
+ public string Username { get; set; }
+
+ public bool IsBot => false;
+ }
+}
diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs
index 94508e3a81..8d91548149 100644
--- a/osu.Game/Online/API/APIAccess.cs
+++ b/osu.Game/Online/API/APIAccess.cs
@@ -17,6 +17,7 @@ using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Game.Configuration;
using osu.Game.Online.API.Requests;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Users;
namespace osu.Game.Online.API
@@ -41,13 +42,13 @@ namespace osu.Game.Online.API
private string password;
- public IBindable LocalUser => localUser;
- public IBindableList Friends => friends;
+ public IBindable LocalUser => localUser;
+ public IBindableList Friends => friends;
public IBindable Activity => activity;
- private Bindable localUser { get; } = new Bindable(createGuestUser());
+ private Bindable localUser { get; } = new Bindable(createGuestUser());
- private BindableList friends { get; } = new BindableList();
+ private BindableList friends { get; } = new BindableList();
private Bindable activity { get; } = new Bindable();
@@ -436,7 +437,7 @@ namespace osu.Game.Online.API
flushQueue();
}
- private static User createGuestUser() => new GuestUser();
+ private static APIUser createGuestUser() => new GuestUser();
protected override void Dispose(bool isDisposing)
{
@@ -447,7 +448,7 @@ namespace osu.Game.Online.API
}
}
- internal class GuestUser : User
+ internal class GuestUser : APIUser
{
public GuestUser()
{
diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs
index 69d72226ba..43195811dc 100644
--- a/osu.Game/Online/API/APIRequest.cs
+++ b/osu.Game/Online/API/APIRequest.cs
@@ -6,7 +6,7 @@ using JetBrains.Annotations;
using Newtonsoft.Json;
using osu.Framework.IO.Network;
using osu.Framework.Logging;
-using osu.Game.Users;
+using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Online.API
{
@@ -69,7 +69,7 @@ namespace osu.Game.Online.API
///
/// The currently logged in user. Note that this will only be populated during .
///
- protected User User { get; private set; }
+ protected APIUser User { get; private set; }
///
/// Invoked on successful completion of an API request.
diff --git a/osu.Game/Online/API/DummyAPIAccess.cs b/osu.Game/Online/API/DummyAPIAccess.cs
index 8f91a4d198..7131c3a7d4 100644
--- a/osu.Game/Online/API/DummyAPIAccess.cs
+++ b/osu.Game/Online/API/DummyAPIAccess.cs
@@ -6,19 +6,20 @@ using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Users;
namespace osu.Game.Online.API
{
public class DummyAPIAccess : Component, IAPIProvider
{
- public Bindable LocalUser { get; } = new Bindable(new User
+ public Bindable LocalUser { get; } = new Bindable(new APIUser
{
Username = @"Dummy",
Id = 1001,
});
- public BindableList Friends { get; } = new BindableList();
+ public BindableList Friends { get; } = new BindableList();
public Bindable Activity { get; } = new Bindable();
@@ -90,7 +91,7 @@ namespace osu.Game.Online.API
}
LastLoginError = null;
- LocalUser.Value = new User
+ LocalUser.Value = new APIUser
{
Username = username,
Id = 1001,
@@ -115,8 +116,8 @@ namespace osu.Game.Online.API
public void SetState(APIState newState) => state.Value = newState;
- IBindable IAPIProvider.LocalUser => LocalUser;
- IBindableList IAPIProvider.Friends => Friends;
+ IBindable IAPIProvider.LocalUser => LocalUser;
+ IBindableList IAPIProvider.Friends => Friends;
IBindable IAPIProvider.Activity => Activity;
public void FailNextLogin() => shouldFailNextLogin = true;
diff --git a/osu.Game/Online/API/IAPIProvider.cs b/osu.Game/Online/API/IAPIProvider.cs
index 72ca37bcf4..a97eae77e3 100644
--- a/osu.Game/Online/API/IAPIProvider.cs
+++ b/osu.Game/Online/API/IAPIProvider.cs
@@ -6,6 +6,7 @@
using System;
using System.Threading.Tasks;
using osu.Framework.Bindables;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Users;
namespace osu.Game.Online.API
@@ -16,13 +17,13 @@ namespace osu.Game.Online.API
/// The local user.
/// This is not thread-safe and should be scheduled locally if consumed from a drawable component.
///
- IBindable LocalUser { get; }
+ IBindable LocalUser { get; }
///
/// The user's friends.
/// This is not thread-safe and should be scheduled locally if consumed from a drawable component.
///
- IBindableList Friends { get; }
+ IBindableList Friends { get; }
///
/// The current user's activity.
diff --git a/osu.Game/Online/API/Requests/CreateNewPrivateMessageRequest.cs b/osu.Game/Online/API/Requests/CreateNewPrivateMessageRequest.cs
index 37ffc04e04..e5761149e7 100644
--- a/osu.Game/Online/API/Requests/CreateNewPrivateMessageRequest.cs
+++ b/osu.Game/Online/API/Requests/CreateNewPrivateMessageRequest.cs
@@ -3,17 +3,17 @@
using System.Net.Http;
using osu.Framework.IO.Network;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Chat;
-using osu.Game.Users;
namespace osu.Game.Online.API.Requests
{
public class CreateNewPrivateMessageRequest : APIRequest
{
- private readonly User user;
+ private readonly APIUser user;
private readonly Message message;
- public CreateNewPrivateMessageRequest(User user, Message message)
+ public CreateNewPrivateMessageRequest(APIUser user, Message message)
{
this.user = user;
this.message = message;
diff --git a/osu.Game/Online/API/Requests/GetFriendsRequest.cs b/osu.Game/Online/API/Requests/GetFriendsRequest.cs
index 46890aa889..63a221d91a 100644
--- a/osu.Game/Online/API/Requests/GetFriendsRequest.cs
+++ b/osu.Game/Online/API/Requests/GetFriendsRequest.cs
@@ -2,11 +2,11 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
-using osu.Game.Users;
+using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Online.API.Requests
{
- public class GetFriendsRequest : APIRequest>
+ public class GetFriendsRequest : APIRequest>
{
protected override string Target => @"friends";
}
diff --git a/osu.Game/Online/API/Requests/GetUserRequest.cs b/osu.Game/Online/API/Requests/GetUserRequest.cs
index 730e4e02ed..e32451fc2f 100644
--- a/osu.Game/Online/API/Requests/GetUserRequest.cs
+++ b/osu.Game/Online/API/Requests/GetUserRequest.cs
@@ -1,12 +1,12 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using osu.Game.Users;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets;
namespace osu.Game.Online.API.Requests
{
- public class GetUserRequest : APIRequest
+ public class GetUserRequest : APIRequest
{
public readonly string Lookup;
public readonly RulesetInfo Ruleset;
diff --git a/osu.Game/Online/API/Requests/GetUsersResponse.cs b/osu.Game/Online/API/Requests/GetUsersResponse.cs
index 6f49d5cd53..022050de5c 100644
--- a/osu.Game/Online/API/Requests/GetUsersResponse.cs
+++ b/osu.Game/Online/API/Requests/GetUsersResponse.cs
@@ -3,13 +3,13 @@
using System.Collections.Generic;
using Newtonsoft.Json;
-using osu.Game.Users;
+using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Online.API.Requests
{
public class GetUsersResponse : ResponseWithCursor
{
[JsonProperty("users")]
- public List Users;
+ public List Users;
}
}
diff --git a/osu.Game/Online/API/Requests/PostBeatmapFavouriteRequest.cs b/osu.Game/Online/API/Requests/PostBeatmapFavouriteRequest.cs
index f3724230cb..9fdc3382aa 100644
--- a/osu.Game/Online/API/Requests/PostBeatmapFavouriteRequest.cs
+++ b/osu.Game/Online/API/Requests/PostBeatmapFavouriteRequest.cs
@@ -8,20 +8,21 @@ namespace osu.Game.Online.API.Requests
{
public class PostBeatmapFavouriteRequest : APIRequest
{
+ public readonly BeatmapFavouriteAction Action;
+
private readonly int id;
- private readonly BeatmapFavouriteAction action;
public PostBeatmapFavouriteRequest(int id, BeatmapFavouriteAction action)
{
this.id = id;
- this.action = action;
+ Action = action;
}
protected override WebRequest CreateWebRequest()
{
var req = base.CreateWebRequest();
req.Method = HttpMethod.Post;
- req.AddParameter(@"action", action.ToString().ToLowerInvariant());
+ req.AddParameter(@"action", Action.ToString().ToLowerInvariant());
return req;
}
diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs
index 47536879b2..168e9d5d51 100644
--- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs
+++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs
@@ -6,7 +6,6 @@ using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Game.Beatmaps;
using osu.Game.Database;
-using osu.Game.Users;
#nullable enable
@@ -62,6 +61,12 @@ namespace osu.Game.Online.API.Requests.Responses
[JsonProperty(@"track_id")]
public int? TrackId { get; set; }
+ [JsonProperty(@"hype")]
+ public BeatmapSetHypeStatus? HypeStatus { get; set; }
+
+ [JsonProperty(@"nominations_summary")]
+ public BeatmapSetNominationStatus? NominationStatus { get; set; }
+
public string Title { get; set; } = string.Empty;
[JsonProperty("title_unicode")]
@@ -72,34 +77,26 @@ namespace osu.Game.Online.API.Requests.Responses
[JsonProperty("artist_unicode")]
public string ArtistUnicode { get; set; } = string.Empty;
- public User? Author = new User();
+ public APIUser Author = new APIUser();
///
- /// Helper property to deserialize a username to .
+ /// Helper property to deserialize a username to .
///
[JsonProperty(@"user_id")]
public int AuthorID
{
- get => Author?.Id ?? 1;
- set
- {
- Author ??= new User();
- Author.Id = value;
- }
+ get => Author.Id;
+ set => Author.Id = value;
}
///
- /// Helper property to deserialize a username to .
+ /// Helper property to deserialize a username to .
///
[JsonProperty(@"creator")]
public string AuthorString
{
- get => Author?.Username ?? string.Empty;
- set
- {
- Author ??= new User();
- Author.Username = value;
- }
+ get => Author.Username;
+ set => Author.Username = value;
}
[JsonProperty(@"availability")]
diff --git a/osu.Game/Online/API/Requests/Responses/APIPlayStyle.cs b/osu.Game/Online/API/Requests/Responses/APIPlayStyle.cs
new file mode 100644
index 0000000000..9573ae1825
--- /dev/null
+++ b/osu.Game/Online/API/Requests/Responses/APIPlayStyle.cs
@@ -0,0 +1,22 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.ComponentModel;
+
+namespace osu.Game.Online.API.Requests.Responses
+{
+ public enum APIPlayStyle
+ {
+ [Description("Keyboard")]
+ Keyboard,
+
+ [Description("Mouse")]
+ Mouse,
+
+ [Description("Tablet")]
+ Tablet,
+
+ [Description("Touch Screen")]
+ Touch,
+ }
+}
diff --git a/osu.Game/Online/API/Requests/Responses/APIRankHistory.cs b/osu.Game/Online/API/Requests/Responses/APIRankHistory.cs
new file mode 100644
index 0000000000..064badcccb
--- /dev/null
+++ b/osu.Game/Online/API/Requests/Responses/APIRankHistory.cs
@@ -0,0 +1,16 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using Newtonsoft.Json;
+
+namespace osu.Game.Online.API.Requests.Responses
+{
+ public class APIRankHistory
+ {
+ [JsonProperty(@"mode")]
+ public string Mode;
+
+ [JsonProperty(@"data")]
+ public int[] Data;
+ }
+}
diff --git a/osu.Game/Online/API/Requests/Responses/APIScoreInfo.cs b/osu.Game/Online/API/Requests/Responses/APIScoreInfo.cs
index 82f56d27fd..d0677eacab 100644
--- a/osu.Game/Online/API/Requests/Responses/APIScoreInfo.cs
+++ b/osu.Game/Online/API/Requests/Responses/APIScoreInfo.cs
@@ -12,7 +12,6 @@ using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
using osu.Game.Scoring.Legacy;
-using osu.Game.Users;
namespace osu.Game.Online.API.Requests.Responses
{
@@ -25,7 +24,7 @@ namespace osu.Game.Online.API.Requests.Responses
public int MaxCombo { get; set; }
[JsonProperty(@"user")]
- public User User { get; set; }
+ public APIUser User { get; set; }
[JsonProperty(@"id")]
public long OnlineID { get; set; }
diff --git a/osu.Game/Online/API/Requests/Responses/APIUser.cs b/osu.Game/Online/API/Requests/Responses/APIUser.cs
index ff422b8292..49edfd036b 100644
--- a/osu.Game/Online/API/Requests/Responses/APIUser.cs
+++ b/osu.Game/Online/API/Requests/Responses/APIUser.cs
@@ -1,14 +1,245 @@
// Copyright (c) ppy Pty Ltd . 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 JetBrains.Annotations;
using Newtonsoft.Json;
+using osu.Framework.Bindables;
using osu.Game.Users;
namespace osu.Game.Online.API.Requests.Responses
{
- public class APIUser
+ public class APIUser : IEquatable, IUser
{
+ [JsonProperty(@"id")]
+ public int Id { get; set; } = 1;
+
+ [JsonProperty(@"join_date")]
+ public DateTimeOffset JoinDate;
+
+ [JsonProperty(@"username")]
+ public string Username { get; set; }
+
+ [JsonProperty(@"previous_usernames")]
+ public string[] PreviousUsernames;
+
+ [JsonProperty(@"country")]
+ public Country Country;
+
+ public readonly Bindable Status = new Bindable();
+
+ public readonly Bindable Activity = new Bindable();
+
+ [JsonProperty(@"profile_colour")]
+ public string Colour;
+
+ [JsonProperty(@"avatar_url")]
+ public string AvatarUrl;
+
+ [JsonProperty(@"cover_url")]
+ public string CoverUrl
+ {
+ get => Cover?.Url;
+ set => Cover = new UserCover { Url = value };
+ }
+
+ [JsonProperty(@"cover")]
+ public UserCover Cover;
+
+ public class UserCover
+ {
+ [JsonProperty(@"custom_url")]
+ public string CustomUrl;
+
+ [JsonProperty(@"url")]
+ public string Url;
+
+ [JsonProperty(@"id")]
+ public int? Id;
+ }
+
+ [JsonProperty(@"is_admin")]
+ public bool IsAdmin;
+
+ [JsonProperty(@"is_supporter")]
+ public bool IsSupporter;
+
+ [JsonProperty(@"support_level")]
+ public int SupportLevel;
+
+ [JsonProperty(@"is_gmt")]
+ public bool IsGMT;
+
+ [JsonProperty(@"is_qat")]
+ public bool IsQAT;
+
+ [JsonProperty(@"is_bng")]
+ public bool IsBNG;
+
+ [JsonProperty(@"is_bot")]
+ public bool IsBot { get; set; }
+
+ [JsonProperty(@"is_active")]
+ public bool Active;
+
+ [JsonProperty(@"is_online")]
+ public bool IsOnline;
+
+ [JsonProperty(@"pm_friends_only")]
+ public bool PMFriendsOnly;
+
+ [JsonProperty(@"interests")]
+ public string Interests;
+
+ [JsonProperty(@"occupation")]
+ public string Occupation;
+
+ [JsonProperty(@"title")]
+ public string Title;
+
+ [JsonProperty(@"location")]
+ public string Location;
+
+ [JsonProperty(@"last_visit")]
+ public DateTimeOffset? LastVisit;
+
+ [JsonProperty(@"twitter")]
+ public string Twitter;
+
+ [JsonProperty(@"discord")]
+ public string Discord;
+
+ [JsonProperty(@"website")]
+ public string Website;
+
+ [JsonProperty(@"post_count")]
+ public int PostCount;
+
+ [JsonProperty(@"comments_count")]
+ public int CommentsCount;
+
+ [JsonProperty(@"follower_count")]
+ public int FollowerCount;
+
+ [JsonProperty(@"mapping_follower_count")]
+ public int MappingFollowerCount;
+
+ [JsonProperty(@"favourite_beatmapset_count")]
+ public int FavouriteBeatmapsetCount;
+
+ [JsonProperty(@"graveyard_beatmapset_count")]
+ public int GraveyardBeatmapsetCount;
+
+ [JsonProperty(@"loved_beatmapset_count")]
+ public int LovedBeatmapsetCount;
+
+ [JsonProperty(@"ranked_beatmapset_count")]
+ public int RankedBeatmapsetCount;
+
+ [JsonProperty(@"pending_beatmapset_count")]
+ public int PendingBeatmapsetCount;
+
+ [JsonProperty(@"scores_best_count")]
+ public int ScoresBestCount;
+
+ [JsonProperty(@"scores_first_count")]
+ public int ScoresFirstCount;
+
+ [JsonProperty(@"scores_recent_count")]
+ public int ScoresRecentCount;
+
+ [JsonProperty(@"beatmap_playcounts_count")]
+ public int BeatmapPlaycountsCount;
+
[JsonProperty]
- public User User;
+ private string[] playstyle
+ {
+ set => PlayStyles = value?.Select(str => Enum.Parse(typeof(APIPlayStyle), str, true)).Cast().ToArray();
+ }
+
+ public APIPlayStyle[] PlayStyles;
+
+ [JsonProperty(@"playmode")]
+ public string PlayMode;
+
+ [JsonProperty(@"profile_order")]
+ public string[] ProfileOrder;
+
+ [JsonProperty(@"kudosu")]
+ public KudosuCount Kudosu;
+
+ public class KudosuCount
+ {
+ [JsonProperty(@"total")]
+ public int Total;
+
+ [JsonProperty(@"available")]
+ public int Available;
+ }
+
+ private UserStatistics statistics;
+
+ ///
+ /// User statistics for the requested ruleset (in the case of a or response).
+ /// Otherwise empty.
+ ///
+ [JsonProperty(@"statistics")]
+ public UserStatistics Statistics
+ {
+ get => statistics ??= new UserStatistics();
+ set
+ {
+ if (statistics != null)
+ // we may already have rank history populated
+ value.RankHistory = statistics.RankHistory;
+
+ statistics = value;
+ }
+ }
+
+ [JsonProperty(@"rank_history")]
+ private APIRankHistory rankHistory
+ {
+ set => statistics.RankHistory = value;
+ }
+
+ [JsonProperty("badges")]
+ public Badge[] Badges;
+
+ [JsonProperty("user_achievements")]
+ public APIUserAchievement[] Achievements;
+
+ [JsonProperty("monthly_playcounts")]
+ public APIUserHistoryCount[] MonthlyPlaycounts;
+
+ [JsonProperty("replays_watched_counts")]
+ public APIUserHistoryCount[] ReplaysWatchedCounts;
+
+ ///
+ /// All user statistics per ruleset's short name (in the case of a response).
+ /// Otherwise empty. Can be altered for testing purposes.
+ ///
+ // todo: this should likely be moved to a separate UserCompact class at some point.
+ [JsonProperty("statistics_rulesets")]
+ [CanBeNull]
+ public Dictionary RulesetsStatistics { get; set; }
+
+ public override string ToString() => Username;
+
+ ///
+ /// A user instance for displaying locally created system messages.
+ ///
+ public static readonly APIUser SYSTEM_USER = new APIUser
+ {
+ Id = 0,
+ Username = "system",
+ Colour = @"9c0101",
+ };
+
+ public int OnlineID => Id;
+
+ public bool Equals(APIUser other) => OnlineID == other?.OnlineID;
}
}
diff --git a/osu.Game/Online/API/Requests/Responses/APIUserAchievement.cs b/osu.Game/Online/API/Requests/Responses/APIUserAchievement.cs
new file mode 100644
index 0000000000..cfba9118c2
--- /dev/null
+++ b/osu.Game/Online/API/Requests/Responses/APIUserAchievement.cs
@@ -0,0 +1,17 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using Newtonsoft.Json;
+
+namespace osu.Game.Online.API.Requests.Responses
+{
+ public class APIUserAchievement
+ {
+ [JsonProperty("achievement_id")]
+ public int ID;
+
+ [JsonProperty("achieved_at")]
+ public DateTimeOffset AchievedAt;
+ }
+}
diff --git a/osu.Game/Users/Team.cs b/osu.Game/Online/API/Requests/Responses/APIUserContainer.cs
similarity index 51%
rename from osu.Game/Users/Team.cs
rename to osu.Game/Online/API/Requests/Responses/APIUserContainer.cs
index b56a083fdf..9eb4a2a4e3 100644
--- a/osu.Game/Users/Team.cs
+++ b/osu.Game/Online/API/Requests/Responses/APIUserContainer.cs
@@ -1,10 +1,13 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-namespace osu.Game.Users
+using Newtonsoft.Json;
+
+namespace osu.Game.Online.API.Requests.Responses
{
- public class Team
+ public class APIUserContainer
{
- public string Name;
+ [JsonProperty]
+ public APIUser User;
}
}
diff --git a/osu.Game/Online/API/Requests/Responses/APIUserHistoryCount.cs b/osu.Game/Online/API/Requests/Responses/APIUserHistoryCount.cs
new file mode 100644
index 0000000000..1226c88c08
--- /dev/null
+++ b/osu.Game/Online/API/Requests/Responses/APIUserHistoryCount.cs
@@ -0,0 +1,17 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using Newtonsoft.Json;
+
+namespace osu.Game.Online.API.Requests.Responses
+{
+ public class APIUserHistoryCount
+ {
+ [JsonProperty("start_date")]
+ public DateTime Date;
+
+ [JsonProperty("count")]
+ public long Count;
+ }
+}
diff --git a/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs b/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs
index 172fa3a583..9a7f0832a6 100644
--- a/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs
+++ b/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs
@@ -3,7 +3,6 @@
using Newtonsoft.Json;
using osu.Game.Scoring;
-using osu.Game.Users;
namespace osu.Game.Online.API.Requests.Responses
{
@@ -31,7 +30,7 @@ namespace osu.Game.Online.API.Requests.Responses
public long UserID { get; set; }
[JsonProperty("user")]
- public User User { get; set; }
+ public APIUser User { get; set; }
[JsonProperty("position")]
public int? Position { get; set; }
diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs
index 32d489432d..13379a40a6 100644
--- a/osu.Game/Online/API/Requests/Responses/Comment.cs
+++ b/osu.Game/Online/API/Requests/Responses/Comment.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using Newtonsoft.Json;
-using osu.Game.Users;
using System;
namespace osu.Game.Online.API.Requests.Responses
@@ -20,7 +19,7 @@ namespace osu.Game.Online.API.Requests.Responses
[JsonProperty(@"user_id")]
public long? UserId { get; set; }
- public User User { get; set; }
+ public APIUser User { get; set; }
[JsonProperty(@"message")]
public string Message { get; set; }
@@ -61,7 +60,7 @@ namespace osu.Game.Online.API.Requests.Responses
[JsonProperty(@"pinned")]
public bool Pinned { get; set; }
- public User EditedUser { get; set; }
+ public APIUser EditedUser { get; set; }
public bool IsTopLevel => !ParentId.HasValue;
diff --git a/osu.Game/Online/API/Requests/Responses/CommentBundle.cs b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs
index 4070df493d..8436381090 100644
--- a/osu.Game/Online/API/Requests/Responses/CommentBundle.cs
+++ b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using Newtonsoft.Json;
-using osu.Game.Users;
using System.Collections.Generic;
using System.Linq;
@@ -43,10 +42,10 @@ namespace osu.Game.Online.API.Requests.Responses
}
}
- private List users;
+ private List users;
[JsonProperty(@"users")]
- public List Users
+ public List Users
{
get => users;
set
diff --git a/osu.Game/Online/BeatmapDownloadTracker.cs b/osu.Game/Online/BeatmapDownloadTracker.cs
index 12cbcdbec7..592dc60d20 100644
--- a/osu.Game/Online/BeatmapDownloadTracker.cs
+++ b/osu.Game/Online/BeatmapDownloadTracker.cs
@@ -3,7 +3,6 @@
using System;
using osu.Framework.Allocation;
-using osu.Framework.Bindables;
using osu.Game.Beatmaps;
using osu.Game.Online.API;
@@ -23,11 +22,6 @@ namespace osu.Game.Online
{
}
- private IBindable>? managerUpdated;
- private IBindable>? managerRemoved;
- private IBindable>>? managerDownloadBegan;
- private IBindable>>? managerDownloadFailed;
-
[BackgroundDependencyLoader(true)]
private void load()
{
@@ -42,39 +36,23 @@ namespace osu.Game.Online
else
attachDownload(Manager.GetExistingDownload(beatmapSetInfo));
- managerDownloadBegan = Manager.DownloadBegan.GetBoundCopy();
- managerDownloadBegan.BindValueChanged(downloadBegan);
- managerDownloadFailed = Manager.DownloadFailed.GetBoundCopy();
- managerDownloadFailed.BindValueChanged(downloadFailed);
- managerUpdated = Manager.ItemUpdated.GetBoundCopy();
- managerUpdated.BindValueChanged(itemUpdated);
- managerRemoved = Manager.ItemRemoved.GetBoundCopy();
- managerRemoved.BindValueChanged(itemRemoved);
+ Manager.DownloadBegan += downloadBegan;
+ Manager.DownloadFailed += downloadFailed;
+ Manager.ItemUpdated += itemUpdated;
+ Manager.ItemRemoved += itemRemoved;
}
- private void downloadBegan(ValueChangedEvent