mirror of
https://github.com/osukey/osukey.git
synced 2025-06-06 20:15:29 +09:00
Merge branch 'master' into fix-autopilot-touch-devices
This commit is contained in:
commit
6bffeb6a24
@ -27,10 +27,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ppy.localisationanalyser.tools": {
|
"ppy.localisationanalyser.tools": {
|
||||||
"version": "2021.725.0",
|
"version": "2021.1210.0",
|
||||||
"commands": [
|
"commands": [
|
||||||
"localisation"
|
"localisation"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1203.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1203.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1207.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1210.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Transitive Dependencies">
|
<ItemGroup Label="Transitive Dependencies">
|
||||||
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
||||||
|
@ -70,7 +70,9 @@ namespace osu.Desktop
|
|||||||
if (!string.IsNullOrEmpty(stableInstallPath) && checkExists(stableInstallPath))
|
if (!string.IsNullOrEmpty(stableInstallPath) && checkExists(stableInstallPath))
|
||||||
return stableInstallPath;
|
return stableInstallPath;
|
||||||
}
|
}
|
||||||
catch { }
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!");
|
stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!");
|
||||||
@ -113,7 +115,7 @@ namespace osu.Desktop
|
|||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
if (!noVersionOverlay)
|
if (!noVersionOverlay)
|
||||||
LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, Add);
|
LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, ScreenContainer.Add);
|
||||||
|
|
||||||
LoadComponentAsync(new DiscordRichPresence(), Add);
|
LoadComponentAsync(new DiscordRichPresence(), Add);
|
||||||
|
|
||||||
|
@ -55,73 +55,75 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
|||||||
|
|
||||||
bool firstDeltaSwitch = false;
|
bool firstDeltaSwitch = false;
|
||||||
|
|
||||||
for (int i = Previous.Count - 2; i > 0; i--)
|
int rhythmStart = 0;
|
||||||
|
|
||||||
|
while (rhythmStart < Previous.Count - 2 && current.StartTime - Previous[rhythmStart].StartTime < history_time_max)
|
||||||
|
rhythmStart++;
|
||||||
|
|
||||||
|
for (int i = rhythmStart; i > 0; i--)
|
||||||
{
|
{
|
||||||
OsuDifficultyHitObject currObj = (OsuDifficultyHitObject)Previous[i - 1];
|
OsuDifficultyHitObject currObj = (OsuDifficultyHitObject)Previous[i - 1];
|
||||||
OsuDifficultyHitObject prevObj = (OsuDifficultyHitObject)Previous[i];
|
OsuDifficultyHitObject prevObj = (OsuDifficultyHitObject)Previous[i];
|
||||||
OsuDifficultyHitObject lastObj = (OsuDifficultyHitObject)Previous[i + 1];
|
OsuDifficultyHitObject lastObj = (OsuDifficultyHitObject)Previous[i + 1];
|
||||||
|
|
||||||
double currHistoricalDecay = Math.Max(0, (history_time_max - (current.StartTime - currObj.StartTime))) / history_time_max; // scales note 0 to 1 from history to now
|
double currHistoricalDecay = (history_time_max - (current.StartTime - currObj.StartTime)) / history_time_max; // scales note 0 to 1 from history to now
|
||||||
|
|
||||||
if (currHistoricalDecay != 0)
|
currHistoricalDecay = Math.Min((double)(Previous.Count - i) / Previous.Count, currHistoricalDecay); // either we're limited by time or limited by object count.
|
||||||
|
|
||||||
|
double currDelta = currObj.StrainTime;
|
||||||
|
double prevDelta = prevObj.StrainTime;
|
||||||
|
double lastDelta = lastObj.StrainTime;
|
||||||
|
double currRatio = 1.0 + 6.0 * Math.Min(0.5, Math.Pow(Math.Sin(Math.PI / (Math.Min(prevDelta, currDelta) / Math.Max(prevDelta, currDelta))), 2)); // fancy function to calculate rhythmbonuses.
|
||||||
|
|
||||||
|
double windowPenalty = Math.Min(1, Math.Max(0, Math.Abs(prevDelta - currDelta) - greatWindow * 0.6) / (greatWindow * 0.6));
|
||||||
|
|
||||||
|
windowPenalty = Math.Min(1, windowPenalty);
|
||||||
|
|
||||||
|
double effectiveRatio = windowPenalty * currRatio;
|
||||||
|
|
||||||
|
if (firstDeltaSwitch)
|
||||||
{
|
{
|
||||||
currHistoricalDecay = Math.Min((double)(Previous.Count - i) / Previous.Count, currHistoricalDecay); // either we're limited by time or limited by object count.
|
if (!(prevDelta > 1.25 * currDelta || prevDelta * 1.25 < currDelta))
|
||||||
|
|
||||||
double currDelta = currObj.StrainTime;
|
|
||||||
double prevDelta = prevObj.StrainTime;
|
|
||||||
double lastDelta = lastObj.StrainTime;
|
|
||||||
double currRatio = 1.0 + 6.0 * Math.Min(0.5, Math.Pow(Math.Sin(Math.PI / (Math.Min(prevDelta, currDelta) / Math.Max(prevDelta, currDelta))), 2)); // fancy function to calculate rhythmbonuses.
|
|
||||||
|
|
||||||
double windowPenalty = Math.Min(1, Math.Max(0, Math.Abs(prevDelta - currDelta) - greatWindow * 0.6) / (greatWindow * 0.6));
|
|
||||||
|
|
||||||
windowPenalty = Math.Min(1, windowPenalty);
|
|
||||||
|
|
||||||
double effectiveRatio = windowPenalty * currRatio;
|
|
||||||
|
|
||||||
if (firstDeltaSwitch)
|
|
||||||
{
|
{
|
||||||
if (!(prevDelta > 1.25 * currDelta || prevDelta * 1.25 < currDelta))
|
if (islandSize < 7)
|
||||||
{
|
islandSize++; // island is still progressing, count size.
|
||||||
if (islandSize < 7)
|
|
||||||
islandSize++; // island is still progressing, count size.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (Previous[i - 1].BaseObject is Slider) // bpm change is into slider, this is easy acc window
|
|
||||||
effectiveRatio *= 0.125;
|
|
||||||
|
|
||||||
if (Previous[i].BaseObject is Slider) // bpm change was from a slider, this is easier typically than circle -> circle
|
|
||||||
effectiveRatio *= 0.25;
|
|
||||||
|
|
||||||
if (previousIslandSize == islandSize) // repeated island size (ex: triplet -> triplet)
|
|
||||||
effectiveRatio *= 0.25;
|
|
||||||
|
|
||||||
if (previousIslandSize % 2 == islandSize % 2) // repeated island polartiy (2 -> 4, 3 -> 5)
|
|
||||||
effectiveRatio *= 0.50;
|
|
||||||
|
|
||||||
if (lastDelta > prevDelta + 10 && prevDelta > currDelta + 10) // previous increase happened a note ago, 1/1->1/2-1/4, dont want to buff this.
|
|
||||||
effectiveRatio *= 0.125;
|
|
||||||
|
|
||||||
rhythmComplexitySum += Math.Sqrt(effectiveRatio * startRatio) * currHistoricalDecay * Math.Sqrt(4 + islandSize) / 2 * Math.Sqrt(4 + previousIslandSize) / 2;
|
|
||||||
|
|
||||||
startRatio = effectiveRatio;
|
|
||||||
|
|
||||||
previousIslandSize = islandSize; // log the last island size.
|
|
||||||
|
|
||||||
if (prevDelta * 1.25 < currDelta) // we're slowing down, stop counting
|
|
||||||
firstDeltaSwitch = false; // if we're speeding up, this stays true and we keep counting island size.
|
|
||||||
|
|
||||||
islandSize = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (prevDelta > 1.25 * currDelta) // we want to be speeding up.
|
else
|
||||||
{
|
{
|
||||||
// Begin counting island until we change speed again.
|
if (Previous[i - 1].BaseObject is Slider) // bpm change is into slider, this is easy acc window
|
||||||
firstDeltaSwitch = true;
|
effectiveRatio *= 0.125;
|
||||||
|
|
||||||
|
if (Previous[i].BaseObject is Slider) // bpm change was from a slider, this is easier typically than circle -> circle
|
||||||
|
effectiveRatio *= 0.25;
|
||||||
|
|
||||||
|
if (previousIslandSize == islandSize) // repeated island size (ex: triplet -> triplet)
|
||||||
|
effectiveRatio *= 0.25;
|
||||||
|
|
||||||
|
if (previousIslandSize % 2 == islandSize % 2) // repeated island polartiy (2 -> 4, 3 -> 5)
|
||||||
|
effectiveRatio *= 0.50;
|
||||||
|
|
||||||
|
if (lastDelta > prevDelta + 10 && prevDelta > currDelta + 10) // previous increase happened a note ago, 1/1->1/2-1/4, dont want to buff this.
|
||||||
|
effectiveRatio *= 0.125;
|
||||||
|
|
||||||
|
rhythmComplexitySum += Math.Sqrt(effectiveRatio * startRatio) * currHistoricalDecay * Math.Sqrt(4 + islandSize) / 2 * Math.Sqrt(4 + previousIslandSize) / 2;
|
||||||
|
|
||||||
startRatio = effectiveRatio;
|
startRatio = effectiveRatio;
|
||||||
|
|
||||||
|
previousIslandSize = islandSize; // log the last island size.
|
||||||
|
|
||||||
|
if (prevDelta * 1.25 < currDelta) // we're slowing down, stop counting
|
||||||
|
firstDeltaSwitch = false; // if we're speeding up, this stays true and we keep counting island size.
|
||||||
|
|
||||||
islandSize = 1;
|
islandSize = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (prevDelta > 1.25 * currDelta) // we want to be speeding up.
|
||||||
|
{
|
||||||
|
// Begin counting island until we change speed again.
|
||||||
|
firstDeltaSwitch = true;
|
||||||
|
startRatio = effectiveRatio;
|
||||||
|
islandSize = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.Sqrt(4 + rhythmComplexitySum * rhythm_multiplier) / 2; //produces multiplier that can be applied to strain. range [1, infinity) (not really though)
|
return Math.Sqrt(4 + rhythmComplexitySum * rhythm_multiplier) / 2; //produces multiplier that can be applied to strain. range [1, infinity) (not really though)
|
||||||
|
@ -62,7 +62,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
public void TestCultureInvariance()
|
public void TestCultureInvariance()
|
||||||
{
|
{
|
||||||
var ruleset = new OsuRuleset().RulesetInfo;
|
var ruleset = new OsuRuleset().RulesetInfo;
|
||||||
var scoreInfo = new TestScoreInfo(ruleset);
|
var scoreInfo = TestResources.CreateTestScoreInfo(ruleset);
|
||||||
var beatmap = new TestBeatmap(ruleset);
|
var beatmap = new TestBeatmap(ruleset);
|
||||||
var score = new Score
|
var score = new Score
|
||||||
{
|
{
|
||||||
|
@ -1022,7 +1022,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
{
|
{
|
||||||
return ImportScoreTest.LoadScoreIntoOsu(osu, new ScoreInfo
|
return ImportScoreTest.LoadScoreIntoOsu(osu, new ScoreInfo
|
||||||
{
|
{
|
||||||
OnlineScoreID = 2,
|
OnlineID = 2,
|
||||||
BeatmapInfo = beatmapInfo,
|
BeatmapInfo = beatmapInfo,
|
||||||
BeatmapInfoID = beatmapInfo.ID
|
BeatmapInfoID = beatmapInfo.ID
|
||||||
}, new ImportScoreTest.TestArchiveReader());
|
}, new ImportScoreTest.TestArchiveReader());
|
||||||
|
@ -809,7 +809,7 @@ namespace osu.Game.Tests.Database
|
|||||||
// TODO: reimplement when we have score support in realm.
|
// TODO: reimplement when we have score support in realm.
|
||||||
// return ImportScoreTest.LoadScoreIntoOsu(osu, new ScoreInfo
|
// return ImportScoreTest.LoadScoreIntoOsu(osu, new ScoreInfo
|
||||||
// {
|
// {
|
||||||
// OnlineScoreID = 2,
|
// OnlineID = 2,
|
||||||
// Beatmap = beatmap,
|
// Beatmap = beatmap,
|
||||||
// BeatmapInfoID = beatmap.ID
|
// BeatmapInfoID = beatmap.ID
|
||||||
// }, new ImportScoreTest.TestArchiveReader());
|
// }, new ImportScoreTest.TestArchiveReader());
|
||||||
|
@ -52,6 +52,45 @@ namespace osu.Game.Tests.Database
|
|||||||
Assert.That(queryCount(GlobalAction.Select), Is.EqualTo(2));
|
Assert.That(queryCount(GlobalAction.Select), Is.EqualTo(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDefaultsPopulationRemovesExcess()
|
||||||
|
{
|
||||||
|
Assert.That(queryCount(), Is.EqualTo(0));
|
||||||
|
|
||||||
|
KeyBindingContainer testContainer = new TestKeyBindingContainer();
|
||||||
|
|
||||||
|
// Add some excess bindings for an action which only supports 1.
|
||||||
|
using (var realm = realmContextFactory.CreateContext())
|
||||||
|
using (var transaction = realm.BeginWrite())
|
||||||
|
{
|
||||||
|
realm.Add(new RealmKeyBinding
|
||||||
|
{
|
||||||
|
Action = GlobalAction.Back,
|
||||||
|
KeyCombination = new KeyCombination(InputKey.A)
|
||||||
|
});
|
||||||
|
|
||||||
|
realm.Add(new RealmKeyBinding
|
||||||
|
{
|
||||||
|
Action = GlobalAction.Back,
|
||||||
|
KeyCombination = new KeyCombination(InputKey.S)
|
||||||
|
});
|
||||||
|
|
||||||
|
realm.Add(new RealmKeyBinding
|
||||||
|
{
|
||||||
|
Action = GlobalAction.Back,
|
||||||
|
KeyCombination = new KeyCombination(InputKey.D)
|
||||||
|
});
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.That(queryCount(GlobalAction.Back), Is.EqualTo(3));
|
||||||
|
|
||||||
|
keyBindingStore.Register(testContainer, Enumerable.Empty<RulesetInfo>());
|
||||||
|
|
||||||
|
Assert.That(queryCount(GlobalAction.Back), Is.EqualTo(1));
|
||||||
|
}
|
||||||
|
|
||||||
private int queryCount(GlobalAction? match = null)
|
private int queryCount(GlobalAction? match = null)
|
||||||
{
|
{
|
||||||
using (var realm = realmContextFactory.CreateContext())
|
using (var realm = realmContextFactory.CreateContext())
|
||||||
|
@ -45,8 +45,6 @@ namespace osu.Game.Tests.NonVisual.Multiplayer
|
|||||||
AddRepeatStep("add some users", () => Client.AddUser(new APIUser { Id = id++ }), 5);
|
AddRepeatStep("add some users", () => Client.AddUser(new APIUser { Id = id++ }), 5);
|
||||||
checkPlayingUserCount(0);
|
checkPlayingUserCount(0);
|
||||||
|
|
||||||
AddAssert("playlist item is available", () => Client.CurrentMatchPlayingItem.Value != null);
|
|
||||||
|
|
||||||
changeState(3, MultiplayerUserState.WaitingForLoad);
|
changeState(3, MultiplayerUserState.WaitingForLoad);
|
||||||
checkPlayingUserCount(3);
|
checkPlayingUserCount(3);
|
||||||
|
|
||||||
@ -64,8 +62,6 @@ namespace osu.Game.Tests.NonVisual.Multiplayer
|
|||||||
|
|
||||||
AddStep("leave room", () => Client.LeaveRoom());
|
AddStep("leave room", () => Client.LeaveRoom());
|
||||||
checkPlayingUserCount(0);
|
checkPlayingUserCount(0);
|
||||||
|
|
||||||
AddAssert("playlist item is null", () => Client.CurrentMatchPlayingItem.Value == null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
90
osu.Game.Tests/Online/Chat/MessageNotifierTest.cs
Normal file
90
osu.Game.Tests/Online/Chat/MessageNotifierTest.cs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Online.Chat;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Online.Chat
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class MessageNotifierTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameMidlinePositive()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(MessageNotifier.CheckContainsUsername("This is a test message", "Test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameStartOfLinePositive()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(MessageNotifier.CheckContainsUsername("Test message", "Test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameEndOfLinePositive()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(MessageNotifier.CheckContainsUsername("This is a test", "Test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameMidlineNegative()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(MessageNotifier.CheckContainsUsername("This is a testmessage for notifications", "Test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameStartOfLineNegative()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(MessageNotifier.CheckContainsUsername("Testmessage", "Test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameEndOfLineNegative()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(MessageNotifier.CheckContainsUsername("This is a notificationtest", "Test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameBetweenInterpunction()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(MessageNotifier.CheckContainsUsername("Hello 'test'-message", "Test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameUnicode()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(MessageNotifier.CheckContainsUsername("Test \u0460\u0460 message", "\u0460\u0460"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameUnicodeNegative()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(MessageNotifier.CheckContainsUsername("Test ha\u0460\u0460o message", "\u0460\u0460"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameSpecialCharactersPositive()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(MessageNotifier.CheckContainsUsername("Test [#^-^#] message", "[#^-^#]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameSpecialCharactersNegative()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(MessageNotifier.CheckContainsUsername("Test pad[#^-^#]oru message", "[#^-^#]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameAtSign()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(MessageNotifier.CheckContainsUsername("@username hi", "username"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestContainsUsernameColon()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(MessageNotifier.CheckContainsUsername("username: hi", "username"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,6 @@ using osu.Game.Online.Solo;
|
|||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu;
|
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
@ -94,7 +93,7 @@ namespace osu.Game.Tests.Online
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestDeserialiseSubmittableScoreWithEmptyMods()
|
public void TestDeserialiseSubmittableScoreWithEmptyMods()
|
||||||
{
|
{
|
||||||
var score = new SubmittableScore(new ScoreInfo { Ruleset = new OsuRuleset().RulesetInfo });
|
var score = new SubmittableScore(new ScoreInfo());
|
||||||
|
|
||||||
var deserialised = JsonConvert.DeserializeObject<SubmittableScore>(JsonConvert.SerializeObject(score));
|
var deserialised = JsonConvert.DeserializeObject<SubmittableScore>(JsonConvert.SerializeObject(score));
|
||||||
|
|
||||||
@ -106,7 +105,6 @@ namespace osu.Game.Tests.Online
|
|||||||
{
|
{
|
||||||
var score = new SubmittableScore(new ScoreInfo
|
var score = new SubmittableScore(new ScoreInfo
|
||||||
{
|
{
|
||||||
Ruleset = new OsuRuleset().RulesetInfo,
|
|
||||||
Mods = new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 2 } } }
|
Mods = new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 2 } } }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -114,18 +114,23 @@ namespace osu.Game.Tests.Online
|
|||||||
public void TestTrackerRespectsChecksum()
|
public void TestTrackerRespectsChecksum()
|
||||||
{
|
{
|
||||||
AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true));
|
AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true));
|
||||||
|
AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).Wait());
|
||||||
|
addAvailabilityCheckStep("initially locally available", BeatmapAvailability.LocallyAvailable);
|
||||||
|
|
||||||
AddStep("import altered beatmap", () =>
|
AddStep("import altered beatmap", () =>
|
||||||
{
|
{
|
||||||
beatmaps.Import(TestResources.GetTestBeatmapForImport(true)).Wait();
|
beatmaps.Import(TestResources.GetTestBeatmapForImport(true)).Wait();
|
||||||
});
|
});
|
||||||
addAvailabilityCheckStep("state still not downloaded", BeatmapAvailability.NotDownloaded);
|
addAvailabilityCheckStep("state not downloaded", BeatmapAvailability.NotDownloaded);
|
||||||
|
|
||||||
AddStep("recreate tracker", () => Child = availabilityTracker = new OnlinePlayBeatmapAvailabilityTracker
|
AddStep("recreate tracker", () => Child = availabilityTracker = new OnlinePlayBeatmapAvailabilityTracker
|
||||||
{
|
{
|
||||||
SelectedItem = { BindTarget = selectedItem }
|
SelectedItem = { BindTarget = selectedItem }
|
||||||
});
|
});
|
||||||
addAvailabilityCheckStep("state not downloaded as well", BeatmapAvailability.NotDownloaded);
|
addAvailabilityCheckStep("state not downloaded as well", BeatmapAvailability.NotDownloaded);
|
||||||
|
|
||||||
|
AddStep("reimport original beatmap", () => beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait());
|
||||||
|
addAvailabilityCheckStep("locally available after re-import", BeatmapAvailability.LocallyAvailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAvailabilityCheckStep(string description, Func<BeatmapAvailability> expected)
|
private void addAvailabilityCheckStep(string description, Func<BeatmapAvailability> expected)
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -12,8 +13,12 @@ using osu.Framework.IO.Stores;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Resources
|
namespace osu.Game.Tests.Resources
|
||||||
{
|
{
|
||||||
@ -137,5 +142,63 @@ namespace osu.Game.Tests.Resources
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a test score model.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ruleset">The ruleset for which the score was set against.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static ScoreInfo CreateTestScoreInfo(RulesetInfo ruleset = null) =>
|
||||||
|
CreateTestScoreInfo(CreateTestBeatmapSetInfo(1, new[] { ruleset ?? new OsuRuleset().RulesetInfo }).Beatmaps.First());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a test score model.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="beatmap">The beatmap for which the score was set against.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static ScoreInfo CreateTestScoreInfo(BeatmapInfo beatmap) => new ScoreInfo
|
||||||
|
{
|
||||||
|
User = new APIUser
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Username = "peppy",
|
||||||
|
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
|
||||||
|
},
|
||||||
|
BeatmapInfo = beatmap,
|
||||||
|
Ruleset = beatmap.Ruleset,
|
||||||
|
RulesetID = beatmap.Ruleset.ID ?? 0,
|
||||||
|
Mods = new Mod[] { new TestModHardRock(), new TestModDoubleTime() },
|
||||||
|
TotalScore = 2845370,
|
||||||
|
Accuracy = 0.95,
|
||||||
|
MaxCombo = 999,
|
||||||
|
Position = 1,
|
||||||
|
Rank = ScoreRank.S,
|
||||||
|
Date = DateTimeOffset.Now,
|
||||||
|
Statistics = new Dictionary<HitResult, int>
|
||||||
|
{
|
||||||
|
[HitResult.Miss] = 1,
|
||||||
|
[HitResult.Meh] = 50,
|
||||||
|
[HitResult.Ok] = 100,
|
||||||
|
[HitResult.Good] = 200,
|
||||||
|
[HitResult.Great] = 300,
|
||||||
|
[HitResult.Perfect] = 320,
|
||||||
|
[HitResult.SmallTickHit] = 50,
|
||||||
|
[HitResult.SmallTickMiss] = 25,
|
||||||
|
[HitResult.LargeTickHit] = 100,
|
||||||
|
[HitResult.LargeTickMiss] = 50,
|
||||||
|
[HitResult.SmallBonus] = 10,
|
||||||
|
[HitResult.SmallBonus] = 50
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
private class TestModHardRock : ModHardRock
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestModDoubleTime : ModDoubleTime
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
Combo = 250,
|
Combo = 250,
|
||||||
User = new APIUser { Username = "Test user" },
|
User = new APIUser { Username = "Test user" },
|
||||||
Date = DateTimeOffset.Now,
|
Date = DateTimeOffset.Now,
|
||||||
OnlineScoreID = 12345,
|
OnlineID = 12345,
|
||||||
};
|
};
|
||||||
|
|
||||||
var imported = await LoadScoreIntoOsu(osu, toImport);
|
var imported = await LoadScoreIntoOsu(osu, toImport);
|
||||||
@ -52,7 +52,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
Assert.AreEqual(toImport.Combo, imported.Combo);
|
Assert.AreEqual(toImport.Combo, imported.Combo);
|
||||||
Assert.AreEqual(toImport.User.Username, imported.User.Username);
|
Assert.AreEqual(toImport.User.Username, imported.User.Username);
|
||||||
Assert.AreEqual(toImport.Date, imported.Date);
|
Assert.AreEqual(toImport.Date, imported.Date);
|
||||||
Assert.AreEqual(toImport.OnlineScoreID, imported.OnlineScoreID);
|
Assert.AreEqual(toImport.OnlineID, imported.OnlineID);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -163,12 +163,12 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
{
|
{
|
||||||
var osu = LoadOsuIntoHost(host, true);
|
var osu = LoadOsuIntoHost(host, true);
|
||||||
|
|
||||||
await LoadScoreIntoOsu(osu, new ScoreInfo { OnlineScoreID = 2 }, new TestArchiveReader());
|
await LoadScoreIntoOsu(osu, new ScoreInfo { OnlineID = 2 }, new TestArchiveReader());
|
||||||
|
|
||||||
var scoreManager = osu.Dependencies.Get<ScoreManager>();
|
var scoreManager = osu.Dependencies.Get<ScoreManager>();
|
||||||
|
|
||||||
// Note: A new score reference is used here since the import process mutates the original object to set an ID
|
// Note: A new score reference is used here since the import process mutates the original object to set an ID
|
||||||
Assert.That(scoreManager.IsAvailableLocally(new ScoreInfo { OnlineScoreID = 2 }));
|
Assert.That(scoreManager.IsAvailableLocally(new ScoreInfo { OnlineID = 2 }));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -44,24 +44,6 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
Assert.That(score1, Is.EqualTo(score2));
|
Assert.That(score1, Is.EqualTo(score2));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestNonMatchingByHash()
|
|
||||||
{
|
|
||||||
ScoreInfo score1 = new ScoreInfo { Hash = "a" };
|
|
||||||
ScoreInfo score2 = new ScoreInfo { Hash = "b" };
|
|
||||||
|
|
||||||
Assert.That(score1, Is.Not.EqualTo(score2));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestMatchingByHash()
|
|
||||||
{
|
|
||||||
ScoreInfo score1 = new ScoreInfo { Hash = "a" };
|
|
||||||
ScoreInfo score2 = new ScoreInfo { Hash = "a" };
|
|
||||||
|
|
||||||
Assert.That(score1, Is.EqualTo(score2));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestNonMatchingByNull()
|
public void TestNonMatchingByNull()
|
||||||
{
|
{
|
||||||
|
@ -5,8 +5,11 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
@ -15,6 +18,7 @@ using osu.Game.Online.API.Requests.Responses;
|
|||||||
using osu.Game.Screens;
|
using osu.Game.Screens;
|
||||||
using osu.Game.Screens.Backgrounds;
|
using osu.Game.Screens.Backgrounds;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Background
|
namespace osu.Game.Tests.Visual.Background
|
||||||
{
|
{
|
||||||
@ -22,8 +26,7 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
public class TestSceneBackgroundScreenDefault : OsuTestScene
|
public class TestSceneBackgroundScreenDefault : OsuTestScene
|
||||||
{
|
{
|
||||||
private BackgroundScreenStack stack;
|
private BackgroundScreenStack stack;
|
||||||
private BackgroundScreenDefault screen;
|
private TestBackgroundScreenDefault screen;
|
||||||
|
|
||||||
private Graphics.Backgrounds.Background getCurrentBackground() => screen.ChildrenOfType<Graphics.Backgrounds.Background>().FirstOrDefault();
|
private Graphics.Backgrounds.Background getCurrentBackground() => screen.ChildrenOfType<Graphics.Backgrounds.Background>().FirstOrDefault();
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
@ -36,10 +39,95 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
public void SetUpSteps()
|
public void SetUpSteps()
|
||||||
{
|
{
|
||||||
AddStep("create background stack", () => Child = stack = new BackgroundScreenStack());
|
AddStep("create background stack", () => Child = stack = new BackgroundScreenStack());
|
||||||
AddStep("push default screen", () => stack.Push(screen = new BackgroundScreenDefault(false)));
|
AddStep("push default screen", () => stack.Push(screen = new TestBackgroundScreenDefault()));
|
||||||
AddUntilStep("wait for screen to load", () => screen.IsCurrentScreen());
|
AddUntilStep("wait for screen to load", () => screen.IsCurrentScreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestBeatmapBackgroundTracksBeatmap()
|
||||||
|
{
|
||||||
|
setSupporter(true);
|
||||||
|
setSourceMode(BackgroundSource.Beatmap);
|
||||||
|
|
||||||
|
AddStep("change beatmap", () => Beatmap.Value = createTestWorkingBeatmapWithUniqueBackground());
|
||||||
|
AddAssert("background changed", () => screen.CheckLastLoadChange() == true);
|
||||||
|
|
||||||
|
Graphics.Backgrounds.Background last = null;
|
||||||
|
|
||||||
|
AddUntilStep("wait for beatmap background to be loaded", () => getCurrentBackground()?.GetType() == typeof(BeatmapBackground));
|
||||||
|
AddStep("store background", () => last = getCurrentBackground());
|
||||||
|
|
||||||
|
AddStep("change beatmap", () => Beatmap.Value = createTestWorkingBeatmapWithUniqueBackground());
|
||||||
|
|
||||||
|
AddUntilStep("wait for beatmap background to change", () => screen.CheckLastLoadChange() == true);
|
||||||
|
|
||||||
|
AddUntilStep("background is new beatmap background", () => last != getCurrentBackground());
|
||||||
|
AddStep("store background", () => last = getCurrentBackground());
|
||||||
|
|
||||||
|
AddStep("change beatmap", () => Beatmap.Value = createTestWorkingBeatmapWithUniqueBackground());
|
||||||
|
|
||||||
|
AddUntilStep("wait for beatmap background to change", () => screen.CheckLastLoadChange() == true);
|
||||||
|
AddUntilStep("background is new beatmap background", () => last != getCurrentBackground());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestBeatmapBackgroundTracksBeatmapWhenSuspended()
|
||||||
|
{
|
||||||
|
setSupporter(true);
|
||||||
|
setSourceMode(BackgroundSource.Beatmap);
|
||||||
|
|
||||||
|
AddStep("change beatmap", () => Beatmap.Value = createTestWorkingBeatmapWithUniqueBackground());
|
||||||
|
AddAssert("background changed", () => screen.CheckLastLoadChange() == true);
|
||||||
|
AddUntilStep("wait for beatmap background to be loaded", () => getCurrentBackground()?.GetType() == typeof(BeatmapBackground));
|
||||||
|
|
||||||
|
BackgroundScreenBeatmap nestedScreen = null;
|
||||||
|
|
||||||
|
// of note, this needs to be a type that doesn't match BackgroundScreenDefault else it is silently not pushed by the background stack.
|
||||||
|
AddStep("push new background to stack", () => stack.Push(nestedScreen = new BackgroundScreenBeatmap(Beatmap.Value)));
|
||||||
|
AddUntilStep("wait for screen to load", () => nestedScreen.IsLoaded && nestedScreen.IsCurrentScreen());
|
||||||
|
|
||||||
|
AddAssert("top level background hasn't changed yet", () => screen.CheckLastLoadChange() == null);
|
||||||
|
|
||||||
|
AddStep("change beatmap", () => Beatmap.Value = createTestWorkingBeatmapWithUniqueBackground());
|
||||||
|
|
||||||
|
AddAssert("top level background hasn't changed yet", () => screen.CheckLastLoadChange() == null);
|
||||||
|
|
||||||
|
AddStep("pop screen back to top level", () => screen.MakeCurrent());
|
||||||
|
|
||||||
|
AddAssert("top level background changed", () => screen.CheckLastLoadChange() == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestBeatmapBackgroundIgnoresNoChangeWhenSuspended()
|
||||||
|
{
|
||||||
|
BackgroundScreenBeatmap nestedScreen = null;
|
||||||
|
WorkingBeatmap originalWorking = null;
|
||||||
|
|
||||||
|
setSupporter(true);
|
||||||
|
setSourceMode(BackgroundSource.Beatmap);
|
||||||
|
|
||||||
|
AddStep("change beatmap", () => originalWorking = Beatmap.Value = createTestWorkingBeatmapWithUniqueBackground());
|
||||||
|
AddAssert("background changed", () => screen.CheckLastLoadChange() == true);
|
||||||
|
AddUntilStep("wait for beatmap background to be loaded", () => getCurrentBackground()?.GetType() == typeof(BeatmapBackground));
|
||||||
|
|
||||||
|
// of note, this needs to be a type that doesn't match BackgroundScreenDefault else it is silently not pushed by the background stack.
|
||||||
|
AddStep("push new background to stack", () => stack.Push(nestedScreen = new BackgroundScreenBeatmap(Beatmap.Value)));
|
||||||
|
AddUntilStep("wait for screen to load", () => nestedScreen.IsLoaded && nestedScreen.IsCurrentScreen());
|
||||||
|
|
||||||
|
// we're testing a case where scheduling may be used to avoid issues, so ensure the scheduler is no longer running.
|
||||||
|
AddUntilStep("wait for top level not alive", () => !screen.IsAlive);
|
||||||
|
|
||||||
|
AddStep("change beatmap", () => Beatmap.Value = createTestWorkingBeatmapWithUniqueBackground());
|
||||||
|
AddStep("change beatmap back", () => Beatmap.Value = originalWorking);
|
||||||
|
|
||||||
|
AddAssert("top level background hasn't changed yet", () => screen.CheckLastLoadChange() == null);
|
||||||
|
|
||||||
|
AddStep("pop screen back to top level", () => screen.MakeCurrent());
|
||||||
|
|
||||||
|
AddStep("top level screen is current", () => screen.IsCurrentScreen());
|
||||||
|
AddAssert("top level background reused existing", () => screen.CheckLastLoadChange() == false);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestBackgroundTypeSwitch()
|
public void TestBackgroundTypeSwitch()
|
||||||
{
|
{
|
||||||
@ -78,36 +166,24 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
[TestCase(BackgroundSource.Skin, typeof(SkinBackground))]
|
[TestCase(BackgroundSource.Skin, typeof(SkinBackground))]
|
||||||
public void TestBackgroundDoesntReloadOnNoChange(BackgroundSource source, Type backgroundType)
|
public void TestBackgroundDoesntReloadOnNoChange(BackgroundSource source, Type backgroundType)
|
||||||
{
|
{
|
||||||
Graphics.Backgrounds.Background last = null;
|
|
||||||
|
|
||||||
setSourceMode(source);
|
setSourceMode(source);
|
||||||
setSupporter(true);
|
setSupporter(true);
|
||||||
if (source == BackgroundSource.Skin)
|
if (source == BackgroundSource.Skin)
|
||||||
setCustomSkin();
|
setCustomSkin();
|
||||||
|
|
||||||
AddUntilStep("wait for beatmap background to be loaded", () => (last = getCurrentBackground())?.GetType() == backgroundType);
|
AddUntilStep("wait for beatmap background to be loaded", () => (getCurrentBackground())?.GetType() == backgroundType);
|
||||||
AddAssert("next doesn't load new background", () => screen.Next() == false);
|
AddAssert("next doesn't load new background", () => screen.Next() == false);
|
||||||
|
|
||||||
// doesn't really need to be checked but might as well.
|
|
||||||
AddWaitStep("wait a bit", 5);
|
|
||||||
AddUntilStep("ensure same background instance", () => last == getCurrentBackground());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestBackgroundCyclingOnDefaultSkin([Values] bool supporter)
|
public void TestBackgroundCyclingOnDefaultSkin([Values] bool supporter)
|
||||||
{
|
{
|
||||||
Graphics.Backgrounds.Background last = null;
|
|
||||||
|
|
||||||
setSourceMode(BackgroundSource.Skin);
|
setSourceMode(BackgroundSource.Skin);
|
||||||
setSupporter(supporter);
|
setSupporter(supporter);
|
||||||
setDefaultSkin();
|
setDefaultSkin();
|
||||||
|
|
||||||
AddUntilStep("wait for beatmap background to be loaded", () => (last = getCurrentBackground())?.GetType() == typeof(Graphics.Backgrounds.Background));
|
AddUntilStep("wait for beatmap background to be loaded", () => (getCurrentBackground())?.GetType() == typeof(Graphics.Backgrounds.Background));
|
||||||
AddAssert("next cycles background", () => screen.Next());
|
AddAssert("next cycles background", () => screen.Next());
|
||||||
|
|
||||||
// doesn't really need to be checked but might as well.
|
|
||||||
AddWaitStep("wait a bit", 5);
|
|
||||||
AddUntilStep("ensure different background instance", () => last != getCurrentBackground());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSourceMode(BackgroundSource source) =>
|
private void setSourceMode(BackgroundSource source) =>
|
||||||
@ -120,6 +196,42 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
Id = API.LocalUser.Value.Id + 1,
|
Id = API.LocalUser.Value.Id + 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
private WorkingBeatmap createTestWorkingBeatmapWithUniqueBackground() => new UniqueBackgroundTestWorkingBeatmap(Audio);
|
||||||
|
|
||||||
|
private class TestBackgroundScreenDefault : BackgroundScreenDefault
|
||||||
|
{
|
||||||
|
private bool? lastLoadTriggerCausedChange;
|
||||||
|
|
||||||
|
public TestBackgroundScreenDefault()
|
||||||
|
: base(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Next()
|
||||||
|
{
|
||||||
|
bool didChange = base.Next();
|
||||||
|
lastLoadTriggerCausedChange = didChange;
|
||||||
|
return didChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool? CheckLastLoadChange()
|
||||||
|
{
|
||||||
|
bool? lastChange = lastLoadTriggerCausedChange;
|
||||||
|
lastLoadTriggerCausedChange = null;
|
||||||
|
return lastChange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UniqueBackgroundTestWorkingBeatmap : TestWorkingBeatmap
|
||||||
|
{
|
||||||
|
public UniqueBackgroundTestWorkingBeatmap(AudioManager audioManager)
|
||||||
|
: base(new Beatmap(), null, audioManager)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Texture GetBackground() => new Texture(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
private void setCustomSkin()
|
private void setCustomSkin()
|
||||||
{
|
{
|
||||||
// feign a skin switch. this doesn't do anything except force CurrentSkin to become a LegacySkin.
|
// feign a skin switch. this doesn't do anything except force CurrentSkin to become a LegacySkin.
|
||||||
|
@ -18,7 +18,6 @@ using osu.Game.Configuration;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
@ -28,7 +27,6 @@ using osu.Game.Screens.Play;
|
|||||||
using osu.Game.Screens.Play.PlayerSettings;
|
using osu.Game.Screens.Play.PlayerSettings;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
using osu.Game.Tests.Beatmaps;
|
|
||||||
using osu.Game.Tests.Resources;
|
using osu.Game.Tests.Resources;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
@ -229,12 +227,7 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
|
|
||||||
FadeAccessibleResults results = null;
|
FadeAccessibleResults results = null;
|
||||||
|
|
||||||
AddStep("Transition to Results", () => player.Push(results = new FadeAccessibleResults(new ScoreInfo
|
AddStep("Transition to Results", () => player.Push(results = new FadeAccessibleResults(TestResources.CreateTestScoreInfo())));
|
||||||
{
|
|
||||||
User = new APIUser { Username = "osu!" },
|
|
||||||
BeatmapInfo = new TestBeatmap(Ruleset.Value).BeatmapInfo,
|
|
||||||
Ruleset = Ruleset.Value,
|
|
||||||
})));
|
|
||||||
|
|
||||||
AddUntilStep("Wait for results is current", () => results.IsCurrentScreen());
|
AddUntilStep("Wait for results is current", () => results.IsCurrentScreen());
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ using osu.Framework.Screens;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Screens.Backgrounds;
|
using osu.Game.Screens.Backgrounds;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
@ -44,6 +45,7 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
protected override void LoadEditor()
|
protected override void LoadEditor()
|
||||||
{
|
{
|
||||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(importedBeatmapSet.Beatmaps.First(b => b.RulesetID == 0));
|
Beatmap.Value = beatmaps.GetWorkingBeatmap(importedBeatmapSet.Beatmaps.First(b => b.RulesetID == 0));
|
||||||
|
SelectedMods.Value = new[] { new ModCinema() };
|
||||||
base.LoadEditor();
|
base.LoadEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +69,7 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
var background = this.ChildrenOfType<BackgroundScreenBeatmap>().Single();
|
var background = this.ChildrenOfType<BackgroundScreenBeatmap>().Single();
|
||||||
return background.Colour == Color4.DarkGray && background.BlurAmount.Value == 0;
|
return background.Colour == Color4.DarkGray && background.BlurAmount.Value == 0;
|
||||||
});
|
});
|
||||||
|
AddAssert("no mods selected", () => SelectedMods.Value.Count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -26,6 +26,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddAssert("total number of results == 1", () =>
|
AddAssert("total number of results == 1", () =>
|
||||||
{
|
{
|
||||||
var score = new ScoreInfo();
|
var score = new ScoreInfo();
|
||||||
|
|
||||||
((FailPlayer)Player).ScoreProcessor.PopulateScore(score);
|
((FailPlayer)Player).ScoreProcessor.PopulateScore(score);
|
||||||
|
|
||||||
return score.Statistics.Values.Sum() == 1;
|
return score.Statistics.Values.Sum() == 1;
|
||||||
|
@ -85,11 +85,12 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
loopGroup.Scale.Add(Easing.None, -20000, -18000, 0, 1);
|
loopGroup.Scale.Add(Easing.None, -20000, -18000, 0, 1);
|
||||||
|
|
||||||
var target = addEventToLoop ? loopGroup : sprite.TimelineGroup;
|
var target = addEventToLoop ? loopGroup : sprite.TimelineGroup;
|
||||||
target.Alpha.Add(Easing.None, firstStoryboardEvent, firstStoryboardEvent + 500, 0, 1);
|
double targetTime = addEventToLoop ? 20000 : 0;
|
||||||
|
target.Alpha.Add(Easing.None, targetTime + firstStoryboardEvent, targetTime + firstStoryboardEvent + 500, 0, 1);
|
||||||
|
|
||||||
// these should be ignored due to being in the future.
|
// these should be ignored due to being in the future.
|
||||||
sprite.TimelineGroup.Alpha.Add(Easing.None, 18000, 20000, 0, 1);
|
sprite.TimelineGroup.Alpha.Add(Easing.None, 18000, 20000, 0, 1);
|
||||||
loopGroup.Alpha.Add(Easing.None, 18000, 20000, 0, 1);
|
loopGroup.Alpha.Add(Easing.None, 38000, 40000, 0, 1);
|
||||||
|
|
||||||
storyboard.GetLayer("Background").Add(sprite);
|
storyboard.GetLayer("Background").Add(sprite);
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
private ScoreInfo getScoreInfo(bool replayAvailable)
|
private ScoreInfo getScoreInfo(bool replayAvailable)
|
||||||
{
|
{
|
||||||
return new APIScoreInfo
|
return new APIScore
|
||||||
{
|
{
|
||||||
OnlineID = 2553163309,
|
OnlineID = 2553163309,
|
||||||
RulesetID = 0,
|
RulesetID = 0,
|
||||||
|
@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestFirstItemSelectedByDefault()
|
public void TestFirstItemSelectedByDefault()
|
||||||
{
|
{
|
||||||
AddAssert("first item selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[0].ID);
|
AddAssert("first item selected", () => Client.Room?.Settings.PlaylistItemId == Client.APIRoom?.Playlist[0].ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -27,13 +27,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
addItem(() => OtherBeatmap);
|
addItem(() => OtherBeatmap);
|
||||||
AddAssert("playlist has 2 items", () => Client.APIRoom?.Playlist.Count == 2);
|
AddAssert("playlist has 2 items", () => Client.APIRoom?.Playlist.Count == 2);
|
||||||
AddAssert("last playlist item is different", () => Client.APIRoom?.Playlist[1].Beatmap.Value.OnlineID == OtherBeatmap.OnlineID);
|
|
||||||
|
|
||||||
addItem(() => InitialBeatmap);
|
addItem(() => InitialBeatmap);
|
||||||
AddAssert("playlist has 3 items", () => Client.APIRoom?.Playlist.Count == 3);
|
AddAssert("playlist has 3 items", () => Client.APIRoom?.Playlist.Count == 3);
|
||||||
AddAssert("last playlist item is different", () => Client.APIRoom?.Playlist[2].Beatmap.Value.OnlineID == InitialBeatmap.OnlineID);
|
|
||||||
|
|
||||||
AddAssert("first item still selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[0].ID);
|
AddAssert("first item still selected", () => Client.Room?.Settings.PlaylistItemId == Client.APIRoom?.Playlist[0].ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -43,7 +41,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
AddAssert("playlist has only one item", () => Client.APIRoom?.Playlist.Count == 1);
|
AddAssert("playlist has only one item", () => Client.APIRoom?.Playlist.Count == 1);
|
||||||
AddAssert("playlist item is expired", () => Client.APIRoom?.Playlist[0].Expired == true);
|
AddAssert("playlist item is expired", () => Client.APIRoom?.Playlist[0].Expired == true);
|
||||||
AddAssert("last item selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[0].ID);
|
AddAssert("last item selected", () => Client.Room?.Settings.PlaylistItemId == Client.APIRoom?.Playlist[0].ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -55,12 +53,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
RunGameplay();
|
RunGameplay();
|
||||||
|
|
||||||
AddAssert("first item expired", () => Client.APIRoom?.Playlist[0].Expired == true);
|
AddAssert("first item expired", () => Client.APIRoom?.Playlist[0].Expired == true);
|
||||||
AddAssert("next item selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[1].ID);
|
AddAssert("next item selected", () => Client.Room?.Settings.PlaylistItemId == Client.APIRoom?.Playlist[1].ID);
|
||||||
|
|
||||||
RunGameplay();
|
RunGameplay();
|
||||||
|
|
||||||
AddAssert("second item expired", () => Client.APIRoom?.Playlist[1].Expired == true);
|
AddAssert("second item expired", () => Client.APIRoom?.Playlist[1].Expired == true);
|
||||||
AddAssert("next item selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[2].ID);
|
AddAssert("next item selected", () => Client.Room?.Settings.PlaylistItemId == Client.APIRoom?.Playlist[2].ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -74,15 +72,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
AddStep("change queue mode", () => Client.ChangeSettings(queueMode: QueueMode.HostOnly));
|
AddStep("change queue mode", () => Client.ChangeSettings(queueMode: QueueMode.HostOnly));
|
||||||
AddAssert("playlist has 3 items", () => Client.APIRoom?.Playlist.Count == 3);
|
AddAssert("playlist has 3 items", () => Client.APIRoom?.Playlist.Count == 3);
|
||||||
AddAssert("playlist item is the other beatmap", () => Client.CurrentMatchPlayingItem.Value?.BeatmapID == OtherBeatmap.OnlineID);
|
AddAssert("item 2 is not expired", () => Client.APIRoom?.Playlist[1].Expired == false);
|
||||||
AddAssert("playlist item is not expired", () => Client.APIRoom?.Playlist[1].Expired == false);
|
AddAssert("current item is the other beatmap", () => Client.Room?.Settings.PlaylistItemId == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestCorrectItemSelectedAfterNewItemAdded()
|
public void TestCorrectItemSelectedAfterNewItemAdded()
|
||||||
{
|
{
|
||||||
addItem(() => OtherBeatmap);
|
addItem(() => OtherBeatmap);
|
||||||
AddAssert("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
|
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addItem(Func<BeatmapInfo> beatmap)
|
private void addItem(Func<BeatmapInfo> beatmap)
|
||||||
|
@ -9,6 +9,7 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Screens.OnlinePlay;
|
using osu.Game.Screens.OnlinePlay;
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Multiplayer
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
@ -20,7 +21,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestFirstItemSelectedByDefault()
|
public void TestFirstItemSelectedByDefault()
|
||||||
{
|
{
|
||||||
AddAssert("first item selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[0].ID);
|
AddAssert("first item selected", () => Client.Room?.Settings.PlaylistItemId == Client.APIRoom?.Playlist[0].ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -28,7 +29,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
selectNewItem(() => InitialBeatmap);
|
selectNewItem(() => InitialBeatmap);
|
||||||
|
|
||||||
AddAssert("playlist item still selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[0].ID);
|
AddAssert("playlist item still selected", () => Client.Room?.Settings.PlaylistItemId == Client.APIRoom?.Playlist[0].ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -36,7 +37,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
selectNewItem(() => OtherBeatmap);
|
selectNewItem(() => OtherBeatmap);
|
||||||
|
|
||||||
AddAssert("playlist item still selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[0].ID);
|
AddAssert("playlist item still selected", () => Client.Room?.Settings.PlaylistItemId == Client.APIRoom?.Playlist[0].ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -47,7 +48,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddAssert("playlist contains two items", () => Client.APIRoom?.Playlist.Count == 2);
|
AddAssert("playlist contains two items", () => Client.APIRoom?.Playlist.Count == 2);
|
||||||
AddAssert("first playlist item expired", () => Client.APIRoom?.Playlist[0].Expired == true);
|
AddAssert("first playlist item expired", () => Client.APIRoom?.Playlist[0].Expired == true);
|
||||||
AddAssert("second playlist item not expired", () => Client.APIRoom?.Playlist[1].Expired == false);
|
AddAssert("second playlist item not expired", () => Client.APIRoom?.Playlist[1].Expired == false);
|
||||||
AddAssert("second playlist item selected", () => Client.CurrentMatchPlayingItem.Value?.ID == Client.APIRoom?.Playlist[1].ID);
|
AddAssert("second playlist item selected", () => Client.Room?.Settings.PlaylistItemId == Client.APIRoom?.Playlist[1].ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -85,6 +86,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
private void selectNewItem(Func<BeatmapInfo> beatmap)
|
private void selectNewItem(Func<BeatmapInfo> beatmap)
|
||||||
{
|
{
|
||||||
|
AddUntilStep("wait for playlist panels to load", () =>
|
||||||
|
{
|
||||||
|
var queueList = this.ChildrenOfType<MultiplayerQueueList>().Single();
|
||||||
|
return queueList.ChildrenOfType<DrawableRoomPlaylistItem>().Count() == queueList.Items.Count;
|
||||||
|
});
|
||||||
|
|
||||||
AddStep("click edit button", () =>
|
AddStep("click edit button", () =>
|
||||||
{
|
{
|
||||||
InputManager.MoveMouseTo(this.ChildrenOfType<DrawableRoomPlaylistItem.PlaylistEditButton>().First());
|
InputManager.MoveMouseTo(this.ChildrenOfType<DrawableRoomPlaylistItem.PlaylistEditButton>().First());
|
||||||
@ -97,7 +104,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(otherBeatmap = beatmap()));
|
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(otherBeatmap = beatmap()));
|
||||||
|
|
||||||
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
|
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
|
||||||
AddUntilStep("selected item is new beatmap", () => Client.CurrentMatchPlayingItem.Value?.Beatmap.Value?.OnlineID == otherBeatmap.OnlineID);
|
AddUntilStep("selected item is new beatmap", () => (CurrentSubScreen as MultiplayerMatchSubScreen)?.SelectedItem.Value?.BeatmapID == otherBeatmap.OnlineID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addItem(Func<BeatmapInfo> beatmap)
|
private void addItem(Func<BeatmapInfo> beatmap)
|
||||||
|
@ -391,9 +391,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("set user ready", () => client.ChangeState(MultiplayerUserState.Ready));
|
pressReadyButton();
|
||||||
AddStep("delete beatmap", () => beatmaps.Delete(importedSet));
|
|
||||||
|
|
||||||
|
AddStep("delete beatmap", () => beatmaps.Delete(importedSet));
|
||||||
AddUntilStep("user state is idle", () => client.LocalUser?.State == MultiplayerUserState.Idle);
|
AddUntilStep("user state is idle", () => client.LocalUser?.State == MultiplayerUserState.Idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,10 +413,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
pressReadyButton();
|
||||||
|
|
||||||
AddStep("Enter song select", () =>
|
AddStep("Enter song select", () =>
|
||||||
{
|
{
|
||||||
var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerScreenStack.CurrentScreen).CurrentSubScreen;
|
var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerScreenStack.CurrentScreen).CurrentSubScreen;
|
||||||
((MultiplayerMatchSubScreen)currentSubScreen).OpenSongSelection(client.CurrentMatchPlayingItem.Value);
|
((MultiplayerMatchSubScreen)currentSubScreen).OpenSongSelection(client.Room?.Settings.PlaylistItemId);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
|
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
|
||||||
@ -592,19 +594,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for ready button to be enabled", () => readyButton.ChildrenOfType<OsuButton>().Single().Enabled.Value);
|
pressReadyButton();
|
||||||
|
pressReadyButton();
|
||||||
AddStep("click ready button", () =>
|
|
||||||
{
|
|
||||||
InputManager.MoveMouseTo(readyButton);
|
|
||||||
InputManager.Click(MouseButton.Left);
|
|
||||||
});
|
|
||||||
|
|
||||||
AddUntilStep("wait for player to be ready", () => client.Room?.Users[0].State == MultiplayerUserState.Ready);
|
|
||||||
AddUntilStep("wait for ready button to be enabled", () => readyButton.ChildrenOfType<OsuButton>().Single().Enabled.Value);
|
|
||||||
|
|
||||||
AddStep("click start button", () => InputManager.Click(MouseButton.Left));
|
|
||||||
|
|
||||||
AddUntilStep("wait for player", () => multiplayerScreenStack.CurrentScreen is Player);
|
AddUntilStep("wait for player", () => multiplayerScreenStack.CurrentScreen is Player);
|
||||||
|
|
||||||
// Gameplay runs in real-time, so we need to incrementally check if gameplay has finished in order to not time out.
|
// Gameplay runs in real-time, so we need to incrementally check if gameplay has finished in order to not time out.
|
||||||
@ -665,7 +656,24 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private MultiplayerReadyButton readyButton => this.ChildrenOfType<MultiplayerReadyButton>().Single();
|
private ReadyButton readyButton => this.ChildrenOfType<ReadyButton>().Single();
|
||||||
|
|
||||||
|
private void pressReadyButton()
|
||||||
|
{
|
||||||
|
AddUntilStep("wait for ready button to be enabled", () => readyButton.Enabled.Value);
|
||||||
|
|
||||||
|
MultiplayerUserState lastState = MultiplayerUserState.Idle;
|
||||||
|
|
||||||
|
AddStep("click ready button", () =>
|
||||||
|
{
|
||||||
|
lastState = client.LocalUser?.State ?? MultiplayerUserState.Idle;
|
||||||
|
|
||||||
|
InputManager.MoveMouseTo(readyButton);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for state change", () => client.LocalUser?.State != lastState);
|
||||||
|
}
|
||||||
|
|
||||||
private void createRoom(Func<Room> room)
|
private void createRoom(Func<Room> room)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||||
|
|
||||||
@ -27,7 +28,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
AddStep("initialise gameplay", () =>
|
AddStep("initialise gameplay", () =>
|
||||||
{
|
{
|
||||||
Stack.Push(player = new MultiplayerPlayer(Client.APIRoom, Client.CurrentMatchPlayingItem.Value, Client.Room?.Users.ToArray()));
|
Stack.Push(player = new MultiplayerPlayer(Client.APIRoom, new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = { Value = Beatmap.Value.BeatmapInfo },
|
||||||
|
Ruleset = { Value = Beatmap.Value.BeatmapInfo.Ruleset }
|
||||||
|
}, Client.Room?.Users.ToArray()));
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen() && player.IsLoaded);
|
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen() && player.IsLoaded);
|
||||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
@ -27,11 +28,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
public class TestSceneMultiplayerQueueList : MultiplayerTestScene
|
public class TestSceneMultiplayerQueueList : MultiplayerTestScene
|
||||||
{
|
{
|
||||||
private MultiplayerQueueList playlist;
|
private readonly Bindable<PlaylistItem> selectedItem = new Bindable<PlaylistItem>();
|
||||||
|
|
||||||
[Cached(typeof(UserLookupCache))]
|
[Cached(typeof(UserLookupCache))]
|
||||||
private readonly TestUserLookupCache userLookupCache = new TestUserLookupCache();
|
private readonly TestUserLookupCache userLookupCache = new TestUserLookupCache();
|
||||||
|
|
||||||
|
private MultiplayerQueueList playlist;
|
||||||
private BeatmapManager beatmaps;
|
private BeatmapManager beatmaps;
|
||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
private BeatmapSetInfo importedSet;
|
private BeatmapSetInfo importedSet;
|
||||||
@ -50,12 +52,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
AddStep("create playlist", () =>
|
AddStep("create playlist", () =>
|
||||||
{
|
{
|
||||||
|
selectedItem.Value = null;
|
||||||
|
|
||||||
Child = playlist = new MultiplayerQueueList
|
Child = playlist = new MultiplayerQueueList
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Size = new Vector2(500, 300),
|
Size = new Vector2(500, 300),
|
||||||
SelectedItem = { BindTarget = Client.CurrentMatchPlayingItem },
|
SelectedItem = { BindTarget = selectedItem },
|
||||||
Items = { BindTarget = Client.APIRoom!.Playlist }
|
Items = { BindTarget = Client.APIRoom!.Playlist }
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -107,22 +111,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddStep("set all players queue mode", () => Client.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers }));
|
AddStep("set all players queue mode", () => Client.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers }));
|
||||||
AddUntilStep("wait for queue mode change", () => Client.APIRoom?.QueueMode.Value == QueueMode.AllPlayers);
|
AddUntilStep("wait for queue mode change", () => Client.APIRoom?.QueueMode.Value == QueueMode.AllPlayers);
|
||||||
|
|
||||||
assertDeleteButtonVisibility(0, false);
|
|
||||||
|
|
||||||
addPlaylistItem(() => API.LocalUser.Value.OnlineID);
|
addPlaylistItem(() => API.LocalUser.Value.OnlineID);
|
||||||
|
|
||||||
|
AddStep("select item 0", () => selectedItem.Value = playlist.ChildrenOfType<RearrangeableListItem<PlaylistItem>>().ElementAt(0).Model);
|
||||||
assertDeleteButtonVisibility(0, false);
|
assertDeleteButtonVisibility(0, false);
|
||||||
assertDeleteButtonVisibility(1, true);
|
assertDeleteButtonVisibility(1, true);
|
||||||
|
|
||||||
// Run through gameplay.
|
AddStep("select item 1", () => selectedItem.Value = playlist.ChildrenOfType<RearrangeableListItem<PlaylistItem>>().ElementAt(1).Model);
|
||||||
AddStep("set state to ready", () => Client.ChangeUserState(API.LocalUser.Value.Id, MultiplayerUserState.Ready));
|
assertDeleteButtonVisibility(0, true);
|
||||||
AddUntilStep("local state is ready", () => Client.LocalUser?.State == MultiplayerUserState.Ready);
|
|
||||||
AddStep("start match", () => Client.StartMatch());
|
|
||||||
AddUntilStep("match started", () => Client.LocalUser?.State == MultiplayerUserState.WaitingForLoad);
|
|
||||||
AddStep("set state to loaded", () => Client.ChangeUserState(API.LocalUser.Value.Id, MultiplayerUserState.Loaded));
|
|
||||||
AddUntilStep("local state is playing", () => Client.LocalUser?.State == MultiplayerUserState.Playing);
|
|
||||||
AddStep("set state to finished play", () => Client.ChangeUserState(API.LocalUser.Value.Id, MultiplayerUserState.FinishedPlay));
|
|
||||||
AddUntilStep("local state is results", () => Client.LocalUser?.State == MultiplayerUserState.Results);
|
|
||||||
|
|
||||||
assertDeleteButtonVisibility(1, false);
|
assertDeleteButtonVisibility(1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Scoring;
|
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Multiplayer
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
{
|
{
|
||||||
@ -22,20 +20,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
var rulesetInfo = new OsuRuleset().RulesetInfo;
|
var rulesetInfo = new OsuRuleset().RulesetInfo;
|
||||||
var beatmapInfo = CreateBeatmap(rulesetInfo).BeatmapInfo;
|
var beatmapInfo = CreateBeatmap(rulesetInfo).BeatmapInfo;
|
||||||
|
var score = TestResources.CreateTestScoreInfo(beatmapInfo);
|
||||||
var score = new ScoreInfo
|
|
||||||
{
|
|
||||||
Rank = ScoreRank.B,
|
|
||||||
TotalScore = 987654,
|
|
||||||
Accuracy = 0.8,
|
|
||||||
MaxCombo = 500,
|
|
||||||
Combo = 250,
|
|
||||||
BeatmapInfo = beatmapInfo,
|
|
||||||
User = new APIUser { Username = "Test user" },
|
|
||||||
Date = DateTimeOffset.Now,
|
|
||||||
OnlineScoreID = 12345,
|
|
||||||
Ruleset = rulesetInfo,
|
|
||||||
};
|
|
||||||
|
|
||||||
PlaylistItem playlistItem = new PlaylistItem
|
PlaylistItem playlistItem = new PlaylistItem
|
||||||
{
|
{
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Scoring;
|
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Multiplayer
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
{
|
{
|
||||||
@ -26,20 +24,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
var rulesetInfo = new OsuRuleset().RulesetInfo;
|
var rulesetInfo = new OsuRuleset().RulesetInfo;
|
||||||
var beatmapInfo = CreateBeatmap(rulesetInfo).BeatmapInfo;
|
var beatmapInfo = CreateBeatmap(rulesetInfo).BeatmapInfo;
|
||||||
|
var score = TestResources.CreateTestScoreInfo(beatmapInfo);
|
||||||
var score = new ScoreInfo
|
|
||||||
{
|
|
||||||
Rank = ScoreRank.B,
|
|
||||||
TotalScore = 987654,
|
|
||||||
Accuracy = 0.8,
|
|
||||||
MaxCombo = 500,
|
|
||||||
Combo = 250,
|
|
||||||
BeatmapInfo = beatmapInfo,
|
|
||||||
User = new APIUser { Username = "Test user" },
|
|
||||||
Date = DateTimeOffset.Now,
|
|
||||||
OnlineScoreID = 12345,
|
|
||||||
Ruleset = rulesetInfo,
|
|
||||||
};
|
|
||||||
|
|
||||||
PlaylistItem playlistItem = new PlaylistItem
|
PlaylistItem playlistItem = new PlaylistItem
|
||||||
{
|
{
|
||||||
|
@ -128,7 +128,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
imported = Game.ScoreManager.Import(new ScoreInfo
|
imported = Game.ScoreManager.Import(new ScoreInfo
|
||||||
{
|
{
|
||||||
Hash = Guid.NewGuid().ToString(),
|
Hash = Guid.NewGuid().ToString(),
|
||||||
OnlineScoreID = i,
|
OnlineID = i,
|
||||||
BeatmapInfo = beatmap.Beatmaps.First(),
|
BeatmapInfo = beatmap.Beatmaps.First(),
|
||||||
Ruleset = ruleset ?? new OsuRuleset().RulesetInfo
|
Ruleset = ruleset ?? new OsuRuleset().RulesetInfo
|
||||||
}).Result.Value;
|
}).Result.Value;
|
||||||
|
@ -47,9 +47,9 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
|
|
||||||
var allScores = new APIScoresCollection
|
var allScores = new APIScoresCollection
|
||||||
{
|
{
|
||||||
Scores = new List<APIScoreInfo>
|
Scores = new List<APIScore>
|
||||||
{
|
{
|
||||||
new APIScoreInfo
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new APIUser
|
User = new APIUser
|
||||||
{
|
{
|
||||||
@ -74,7 +74,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
TotalScore = 1234567890,
|
TotalScore = 1234567890,
|
||||||
Accuracy = 1,
|
Accuracy = 1,
|
||||||
},
|
},
|
||||||
new APIScoreInfo
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new APIUser
|
User = new APIUser
|
||||||
{
|
{
|
||||||
@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
TotalScore = 1234789,
|
TotalScore = 1234789,
|
||||||
Accuracy = 0.9997,
|
Accuracy = 0.9997,
|
||||||
},
|
},
|
||||||
new APIScoreInfo
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new APIUser
|
User = new APIUser
|
||||||
{
|
{
|
||||||
@ -121,7 +121,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
TotalScore = 12345678,
|
TotalScore = 12345678,
|
||||||
Accuracy = 0.9854,
|
Accuracy = 0.9854,
|
||||||
},
|
},
|
||||||
new APIScoreInfo
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new APIUser
|
User = new APIUser
|
||||||
{
|
{
|
||||||
@ -143,7 +143,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
TotalScore = 1234567,
|
TotalScore = 1234567,
|
||||||
Accuracy = 0.8765,
|
Accuracy = 0.8765,
|
||||||
},
|
},
|
||||||
new APIScoreInfo
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new APIUser
|
User = new APIUser
|
||||||
{
|
{
|
||||||
@ -166,7 +166,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
|
|
||||||
var myBestScore = new APIScoreWithPosition
|
var myBestScore = new APIScoreWithPosition
|
||||||
{
|
{
|
||||||
Score = new APIScoreInfo
|
Score = new APIScore
|
||||||
{
|
{
|
||||||
User = new APIUser
|
User = new APIUser
|
||||||
{
|
{
|
||||||
@ -189,7 +189,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
|
|
||||||
var myBestScoreWithNullPosition = new APIScoreWithPosition
|
var myBestScoreWithNullPosition = new APIScoreWithPosition
|
||||||
{
|
{
|
||||||
Score = new APIScoreInfo
|
Score = new APIScore
|
||||||
{
|
{
|
||||||
User = new APIUser
|
User = new APIUser
|
||||||
{
|
{
|
||||||
@ -212,9 +212,9 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
|
|
||||||
var oneScore = new APIScoresCollection
|
var oneScore = new APIScoresCollection
|
||||||
{
|
{
|
||||||
Scores = new List<APIScoreInfo>
|
Scores = new List<APIScore>
|
||||||
{
|
{
|
||||||
new APIScoreInfo
|
new APIScore
|
||||||
{
|
{
|
||||||
User = new APIUser
|
User = new APIUser
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
public TestSceneUserProfileScores()
|
public TestSceneUserProfileScores()
|
||||||
{
|
{
|
||||||
var firstScore = new APIScoreInfo
|
var firstScore = new APIScore
|
||||||
{
|
{
|
||||||
PP = 1047.21,
|
PP = 1047.21,
|
||||||
Rank = ScoreRank.SH,
|
Rank = ScoreRank.SH,
|
||||||
@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
Accuracy = 0.9813
|
Accuracy = 0.9813
|
||||||
};
|
};
|
||||||
|
|
||||||
var secondScore = new APIScoreInfo
|
var secondScore = new APIScore
|
||||||
{
|
{
|
||||||
PP = 134.32,
|
PP = 134.32,
|
||||||
Rank = ScoreRank.A,
|
Rank = ScoreRank.A,
|
||||||
@ -64,7 +64,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
Accuracy = 0.998546
|
Accuracy = 0.998546
|
||||||
};
|
};
|
||||||
|
|
||||||
var thirdScore = new APIScoreInfo
|
var thirdScore = new APIScore
|
||||||
{
|
{
|
||||||
PP = 96.83,
|
PP = 96.83,
|
||||||
Rank = ScoreRank.S,
|
Rank = ScoreRank.S,
|
||||||
@ -81,7 +81,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
Accuracy = 0.9726
|
Accuracy = 0.9726
|
||||||
};
|
};
|
||||||
|
|
||||||
var noPPScore = new APIScoreInfo
|
var noPPScore = new APIScore
|
||||||
{
|
{
|
||||||
Rank = ScoreRank.B,
|
Rank = ScoreRank.B,
|
||||||
Beatmap = new APIBeatmap
|
Beatmap = new APIBeatmap
|
||||||
|
@ -22,14 +22,17 @@ using osu.Game.Scoring;
|
|||||||
using osu.Game.Screens.OnlinePlay.Playlists;
|
using osu.Game.Screens.OnlinePlay.Playlists;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Playlists
|
namespace osu.Game.Tests.Visual.Playlists
|
||||||
{
|
{
|
||||||
public class TestScenePlaylistsResultsScreen : ScreenTestScene
|
public class TestScenePlaylistsResultsScreen : ScreenTestScene
|
||||||
{
|
{
|
||||||
private const int scores_per_result = 10;
|
private const int scores_per_result = 10;
|
||||||
|
private const int real_user_position = 200;
|
||||||
|
|
||||||
private TestResultsScreen resultsScreen;
|
private TestResultsScreen resultsScreen;
|
||||||
|
|
||||||
private int currentScoreId;
|
private int currentScoreId;
|
||||||
private bool requestComplete;
|
private bool requestComplete;
|
||||||
private int totalCount;
|
private int totalCount;
|
||||||
@ -37,7 +40,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup() => Schedule(() =>
|
public void Setup() => Schedule(() =>
|
||||||
{
|
{
|
||||||
currentScoreId = 0;
|
currentScoreId = 1;
|
||||||
requestComplete = false;
|
requestComplete = false;
|
||||||
totalCount = 0;
|
totalCount = 0;
|
||||||
bindHandler();
|
bindHandler();
|
||||||
@ -50,13 +53,17 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
|
|
||||||
AddStep("bind user score info handler", () =>
|
AddStep("bind user score info handler", () =>
|
||||||
{
|
{
|
||||||
userScore = new TestScoreInfo(new OsuRuleset().RulesetInfo) { OnlineScoreID = currentScoreId++ };
|
userScore = TestResources.CreateTestScoreInfo();
|
||||||
|
userScore.OnlineID = currentScoreId++;
|
||||||
|
|
||||||
bindHandler(userScore: userScore);
|
bindHandler(userScore: userScore);
|
||||||
});
|
});
|
||||||
|
|
||||||
createResults(() => userScore);
|
createResults(() => userScore);
|
||||||
|
|
||||||
AddAssert("user score selected", () => this.ChildrenOfType<ScorePanel>().Single(p => p.Score.OnlineScoreID == userScore.OnlineScoreID).State == PanelState.Expanded);
|
AddAssert("user score selected", () => this.ChildrenOfType<ScorePanel>().Single(p => p.Score.OnlineID == userScore.OnlineID).State == PanelState.Expanded);
|
||||||
|
AddAssert($"score panel position is {real_user_position}",
|
||||||
|
() => this.ChildrenOfType<ScorePanel>().Single(p => p.Score.OnlineID == userScore.OnlineID).ScorePosition.Value == real_user_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -74,14 +81,16 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
|
|
||||||
AddStep("bind user score info handler", () =>
|
AddStep("bind user score info handler", () =>
|
||||||
{
|
{
|
||||||
userScore = new TestScoreInfo(new OsuRuleset().RulesetInfo) { OnlineScoreID = currentScoreId++ };
|
userScore = TestResources.CreateTestScoreInfo();
|
||||||
|
userScore.OnlineID = currentScoreId++;
|
||||||
|
|
||||||
bindHandler(true, userScore);
|
bindHandler(true, userScore);
|
||||||
});
|
});
|
||||||
|
|
||||||
createResults(() => userScore);
|
createResults(() => userScore);
|
||||||
|
|
||||||
AddAssert("more than 1 panel displayed", () => this.ChildrenOfType<ScorePanel>().Count() > 1);
|
AddAssert("more than 1 panel displayed", () => this.ChildrenOfType<ScorePanel>().Count() > 1);
|
||||||
AddAssert("user score selected", () => this.ChildrenOfType<ScorePanel>().Single(p => p.Score.OnlineScoreID == userScore.OnlineScoreID).State == PanelState.Expanded);
|
AddAssert("user score selected", () => this.ChildrenOfType<ScorePanel>().Single(p => p.Score.OnlineID == userScore.OnlineID).State == PanelState.Expanded);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -123,7 +132,9 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
|
|
||||||
AddStep("bind user score info handler", () =>
|
AddStep("bind user score info handler", () =>
|
||||||
{
|
{
|
||||||
userScore = new TestScoreInfo(new OsuRuleset().RulesetInfo) { OnlineScoreID = currentScoreId++ };
|
userScore = TestResources.CreateTestScoreInfo();
|
||||||
|
userScore.OnlineID = currentScoreId++;
|
||||||
|
|
||||||
bindHandler(userScore: userScore);
|
bindHandler(userScore: userScore);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -230,12 +241,12 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
{
|
{
|
||||||
var multiplayerUserScore = new MultiplayerScore
|
var multiplayerUserScore = new MultiplayerScore
|
||||||
{
|
{
|
||||||
ID = (int)(userScore.OnlineScoreID ?? currentScoreId++),
|
ID = (int)(userScore.OnlineID > 0 ? userScore.OnlineID : currentScoreId++),
|
||||||
Accuracy = userScore.Accuracy,
|
Accuracy = userScore.Accuracy,
|
||||||
EndedAt = userScore.Date,
|
EndedAt = userScore.Date,
|
||||||
Passed = userScore.Passed,
|
Passed = userScore.Passed,
|
||||||
Rank = userScore.Rank,
|
Rank = userScore.Rank,
|
||||||
Position = 200,
|
Position = real_user_position,
|
||||||
MaxCombo = userScore.MaxCombo,
|
MaxCombo = userScore.MaxCombo,
|
||||||
TotalScore = userScore.TotalScore,
|
TotalScore = userScore.TotalScore,
|
||||||
User = userScore.User,
|
User = userScore.User,
|
||||||
|
@ -15,9 +15,11 @@ using osu.Game.Database;
|
|||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Screens.OnlinePlay.Components;
|
using osu.Game.Screens.OnlinePlay.Components;
|
||||||
using osu.Game.Screens.OnlinePlay.Playlists;
|
using osu.Game.Screens.OnlinePlay.Playlists;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
using osu.Game.Tests.Visual.OnlinePlay;
|
using osu.Game.Tests.Visual.OnlinePlay;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
@ -112,37 +114,80 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestBeatmapUpdatedOnReImport()
|
public void TestBeatmapUpdatedOnReImport()
|
||||||
{
|
{
|
||||||
BeatmapSetInfo importedSet = null;
|
string realHash = null;
|
||||||
|
int realOnlineId = 0;
|
||||||
|
int realOnlineSetId = 0;
|
||||||
|
|
||||||
AddStep("import altered beatmap", () =>
|
AddStep("store real beatmap values", () =>
|
||||||
{
|
{
|
||||||
IBeatmap beatmap = CreateBeatmap(new OsuRuleset().RulesetInfo);
|
realHash = importedBeatmap.Value.Beatmaps[0].MD5Hash;
|
||||||
|
realOnlineId = importedBeatmap.Value.Beatmaps[0].OnlineID ?? -1;
|
||||||
beatmap.BeatmapInfo.BaseDifficulty.CircleSize = 1;
|
realOnlineSetId = importedBeatmap.Value.OnlineID ?? -1;
|
||||||
|
|
||||||
// intentionally increment online IDs to clash with import below.
|
|
||||||
beatmap.BeatmapInfo.OnlineID++;
|
|
||||||
beatmap.BeatmapInfo.BeatmapSet.OnlineID++;
|
|
||||||
|
|
||||||
importedSet = manager.Import(beatmap.BeatmapInfo.BeatmapSet).Result.Value;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AddStep("import modified beatmap", () =>
|
||||||
|
{
|
||||||
|
var modifiedBeatmap = new TestBeatmap(new OsuRuleset().RulesetInfo)
|
||||||
|
{
|
||||||
|
BeatmapInfo =
|
||||||
|
{
|
||||||
|
OnlineID = realOnlineId,
|
||||||
|
BeatmapSet =
|
||||||
|
{
|
||||||
|
OnlineID = realOnlineSetId
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
modifiedBeatmap.HitObjects.Clear();
|
||||||
|
modifiedBeatmap.HitObjects.Add(new HitCircle { StartTime = 5000 });
|
||||||
|
|
||||||
|
manager.Import(modifiedBeatmap.BeatmapInfo.BeatmapSet).Wait();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create the room using the real beatmap values.
|
||||||
setupAndCreateRoom(room =>
|
setupAndCreateRoom(room =>
|
||||||
{
|
{
|
||||||
room.Name.Value = "my awesome room";
|
room.Name.Value = "my awesome room";
|
||||||
room.Host.Value = API.LocalUser.Value;
|
room.Host.Value = API.LocalUser.Value;
|
||||||
room.Playlist.Add(new PlaylistItem
|
room.Playlist.Add(new PlaylistItem
|
||||||
{
|
{
|
||||||
Beatmap = { Value = importedSet.Beatmaps[0] },
|
Beatmap =
|
||||||
|
{
|
||||||
|
Value = new BeatmapInfo
|
||||||
|
{
|
||||||
|
MD5Hash = realHash,
|
||||||
|
OnlineID = realOnlineId,
|
||||||
|
BeatmapSet = new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
OnlineID = realOnlineSetId,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
Ruleset = { Value = new OsuRuleset().RulesetInfo }
|
Ruleset = { Value = new OsuRuleset().RulesetInfo }
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("match has altered beatmap", () => match.Beatmap.Value.Beatmap.Difficulty.CircleSize == 1);
|
AddAssert("match has default beatmap", () => match.Beatmap.IsDefault);
|
||||||
|
|
||||||
importBeatmap();
|
AddStep("reimport original beatmap", () =>
|
||||||
|
{
|
||||||
|
var originalBeatmap = new TestBeatmap(new OsuRuleset().RulesetInfo)
|
||||||
|
{
|
||||||
|
BeatmapInfo =
|
||||||
|
{
|
||||||
|
OnlineID = realOnlineId,
|
||||||
|
BeatmapSet =
|
||||||
|
{
|
||||||
|
OnlineID = realOnlineSetId
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
AddAssert("match has original beatmap", () => match.Beatmap.Value.Beatmap.Difficulty.CircleSize != 1);
|
manager.Import(originalBeatmap.BeatmapInfo.BeatmapSet).Wait();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("match has correct beatmap", () => realHash == match.Beatmap.Value.BeatmapInfo.MD5Hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupAndCreateRoom(Action<Room> room)
|
private void setupAndCreateRoom(Action<Room> room)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -13,6 +14,7 @@ using osu.Game.Rulesets.Osu;
|
|||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
using osu.Game.Screens.Ranking.Contracted;
|
using osu.Game.Screens.Ranking.Contracted;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Ranking
|
namespace osu.Game.Tests.Visual.Ranking
|
||||||
@ -22,13 +24,18 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestShowPanel()
|
public void TestShowPanel()
|
||||||
{
|
{
|
||||||
AddStep("show example score", () => showPanel(CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)), new TestScoreInfo(new OsuRuleset().RulesetInfo)));
|
AddStep("show example score", () => showPanel(CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)), TestResources.CreateTestScoreInfo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestExcessMods()
|
public void TestExcessMods()
|
||||||
{
|
{
|
||||||
AddStep("show excess mods score", () => showPanel(CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)), new TestScoreInfo(new OsuRuleset().RulesetInfo, true)));
|
AddStep("show excess mods score", () =>
|
||||||
|
{
|
||||||
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
score.Mods = score.BeatmapInfo.Ruleset.CreateInstance().CreateAllMods().ToArray();
|
||||||
|
showPanel(CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)), score);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showPanel(WorkingBeatmap workingBeatmap, ScoreInfo score)
|
private void showPanel(WorkingBeatmap workingBeatmap, ScoreInfo score)
|
||||||
|
@ -20,6 +20,7 @@ using osu.Game.Scoring;
|
|||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
using osu.Game.Screens.Ranking.Expanded;
|
using osu.Game.Screens.Ranking.Expanded;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Ranking
|
namespace osu.Game.Tests.Visual.Ranking
|
||||||
@ -34,21 +35,21 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
{
|
{
|
||||||
var author = new APIUser { Username = "mapper_name" };
|
var author = new APIUser { Username = "mapper_name" };
|
||||||
|
|
||||||
AddStep("show example score", () => showPanel(new TestScoreInfo(new OsuRuleset().RulesetInfo)
|
AddStep("show example score", () => showPanel(TestResources.CreateTestScoreInfo(createTestBeatmap(author))));
|
||||||
{
|
|
||||||
BeatmapInfo = createTestBeatmap(author)
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestExcessMods()
|
public void TestExcessMods()
|
||||||
{
|
{
|
||||||
var author = new APIUser { Username = "mapper_name" };
|
AddStep("show excess mods score", () =>
|
||||||
|
|
||||||
AddStep("show excess mods score", () => showPanel(new TestScoreInfo(new OsuRuleset().RulesetInfo, true)
|
|
||||||
{
|
{
|
||||||
BeatmapInfo = createTestBeatmap(author)
|
var author = new APIUser { Username = "mapper_name" };
|
||||||
}));
|
|
||||||
|
var score = TestResources.CreateTestScoreInfo(createTestBeatmap(author));
|
||||||
|
score.Mods = score.BeatmapInfo.Ruleset.CreateInstance().CreateAllMods().ToArray();
|
||||||
|
|
||||||
|
showPanel(score);
|
||||||
|
});
|
||||||
|
|
||||||
AddAssert("mapper name present", () => this.ChildrenOfType<OsuSpriteText>().Any(spriteText => spriteText.Current.Value == "mapper_name"));
|
AddAssert("mapper name present", () => this.ChildrenOfType<OsuSpriteText>().Any(spriteText => spriteText.Current.Value == "mapper_name"));
|
||||||
}
|
}
|
||||||
@ -56,10 +57,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestMapWithUnknownMapper()
|
public void TestMapWithUnknownMapper()
|
||||||
{
|
{
|
||||||
AddStep("show example score", () => showPanel(new TestScoreInfo(new OsuRuleset().RulesetInfo)
|
AddStep("show example score", () => showPanel(TestResources.CreateTestScoreInfo(createTestBeatmap(new APIUser()))));
|
||||||
{
|
|
||||||
BeatmapInfo = createTestBeatmap(new APIUser())
|
|
||||||
}));
|
|
||||||
|
|
||||||
AddAssert("mapped by text not present", () =>
|
AddAssert("mapped by text not present", () =>
|
||||||
this.ChildrenOfType<OsuSpriteText>().All(spriteText => !containsAny(spriteText.Text.ToString(), "mapped", "by")));
|
this.ChildrenOfType<OsuSpriteText>().All(spriteText => !containsAny(spriteText.Text.ToString(), "mapped", "by")));
|
||||||
@ -77,12 +75,12 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
var mods = new Mod[] { ruleset.GetAutoplayMod() };
|
var mods = new Mod[] { ruleset.GetAutoplayMod() };
|
||||||
var beatmap = createTestBeatmap(new APIUser());
|
var beatmap = createTestBeatmap(new APIUser());
|
||||||
|
|
||||||
showPanel(new TestScoreInfo(ruleset.RulesetInfo)
|
var score = TestResources.CreateTestScoreInfo(beatmap);
|
||||||
{
|
|
||||||
Mods = mods,
|
score.Mods = mods;
|
||||||
BeatmapInfo = beatmap,
|
score.Date = default;
|
||||||
Date = default,
|
|
||||||
});
|
showPanel(score);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("play time not displayed", () => !this.ChildrenOfType<ExpandedPanelMiddleContent.PlayedOnText>().Any());
|
AddAssert("play time not displayed", () => !this.ChildrenOfType<ExpandedPanelMiddleContent.PlayedOnText>().Any());
|
||||||
|
@ -5,8 +5,8 @@ using osu.Framework.Extensions.Color4Extensions;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Rulesets.Osu;
|
|
||||||
using osu.Game.Screens.Ranking.Expanded;
|
using osu.Game.Screens.Ranking.Expanded;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Ranking
|
namespace osu.Game.Tests.Visual.Ranking
|
||||||
@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = Color4Extensions.FromHex("#444"),
|
Colour = Color4Extensions.FromHex("#444"),
|
||||||
},
|
},
|
||||||
new ExpandedPanelTopContent(new TestScoreInfo(new OsuRuleset().RulesetInfo).User),
|
new ExpandedPanelTopContent(TestResources.CreateTestScoreInfo().User),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,12 @@ using osu.Framework.Utils;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Rulesets.Osu;
|
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens;
|
using osu.Game.Screens;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
using osu.Game.Screens.Ranking.Statistics;
|
using osu.Game.Screens.Ranking.Statistics;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
@ -72,11 +72,10 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
{
|
{
|
||||||
TestResultsScreen screen = null;
|
TestResultsScreen screen = null;
|
||||||
|
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo)
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
{
|
|
||||||
Accuracy = accuracy,
|
score.Accuracy = accuracy;
|
||||||
Rank = rank
|
score.Rank = rank;
|
||||||
};
|
|
||||||
|
|
||||||
AddStep("load results", () => Child = new TestResultsContainer(screen = createResultsScreen(score)));
|
AddStep("load results", () => Child = new TestResultsContainer(screen = createResultsScreen(score)));
|
||||||
AddUntilStep("wait for loaded", () => screen.IsLoaded);
|
AddUntilStep("wait for loaded", () => screen.IsLoaded);
|
||||||
@ -204,7 +203,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
{
|
{
|
||||||
DelayedFetchResultsScreen screen = null;
|
DelayedFetchResultsScreen screen = null;
|
||||||
|
|
||||||
AddStep("load results", () => Child = new TestResultsContainer(screen = new DelayedFetchResultsScreen(new TestScoreInfo(new OsuRuleset().RulesetInfo), 3000)));
|
AddStep("load results", () => Child = new TestResultsContainer(screen = new DelayedFetchResultsScreen(TestResources.CreateTestScoreInfo(), 3000)));
|
||||||
AddUntilStep("wait for loaded", () => screen.IsLoaded);
|
AddUntilStep("wait for loaded", () => screen.IsLoaded);
|
||||||
AddStep("click expanded panel", () =>
|
AddStep("click expanded panel", () =>
|
||||||
{
|
{
|
||||||
@ -237,9 +236,9 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
AddAssert("download button is enabled", () => screen.ChildrenOfType<DownloadButton>().Last().Enabled.Value);
|
AddAssert("download button is enabled", () => screen.ChildrenOfType<DownloadButton>().Last().Enabled.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestResultsScreen createResultsScreen(ScoreInfo score = null) => new TestResultsScreen(score ?? new TestScoreInfo(new OsuRuleset().RulesetInfo));
|
private TestResultsScreen createResultsScreen(ScoreInfo score = null) => new TestResultsScreen(score ?? TestResources.CreateTestScoreInfo());
|
||||||
|
|
||||||
private UnrankedSoloResultsScreen createUnrankedSoloResultsScreen() => new UnrankedSoloResultsScreen(new TestScoreInfo(new OsuRuleset().RulesetInfo));
|
private UnrankedSoloResultsScreen createUnrankedSoloResultsScreen() => new UnrankedSoloResultsScreen(TestResources.CreateTestScoreInfo());
|
||||||
|
|
||||||
private class TestResultsContainer : Container
|
private class TestResultsContainer : Container
|
||||||
{
|
{
|
||||||
@ -282,7 +281,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
|
|
||||||
for (int i = 0; i < 20; i++)
|
for (int i = 0; i < 20; i++)
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo);
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
score.TotalScore += 10 - i;
|
score.TotalScore += 10 - i;
|
||||||
score.Hash = $"test{i}";
|
score.Hash = $"test{i}";
|
||||||
scores.Add(score);
|
scores.Add(score);
|
||||||
@ -316,7 +315,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
|
|
||||||
for (int i = 0; i < 20; i++)
|
for (int i = 0; i < 20; i++)
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo);
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
score.TotalScore += 10 - i;
|
score.TotalScore += 10 - i;
|
||||||
scores.Add(score);
|
scores.Add(score);
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Osu;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Ranking
|
namespace osu.Game.Tests.Visual.Ranking
|
||||||
{
|
{
|
||||||
@ -17,7 +17,9 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestDRank()
|
public void TestDRank()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo) { Accuracy = 0.5, Rank = ScoreRank.D };
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
score.Accuracy = 0.5;
|
||||||
|
score.Rank = ScoreRank.D;
|
||||||
|
|
||||||
addPanelStep(score);
|
addPanelStep(score);
|
||||||
}
|
}
|
||||||
@ -25,7 +27,9 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestCRank()
|
public void TestCRank()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo) { Accuracy = 0.75, Rank = ScoreRank.C };
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
score.Accuracy = 0.75;
|
||||||
|
score.Rank = ScoreRank.C;
|
||||||
|
|
||||||
addPanelStep(score);
|
addPanelStep(score);
|
||||||
}
|
}
|
||||||
@ -33,7 +37,9 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestBRank()
|
public void TestBRank()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo) { Accuracy = 0.85, Rank = ScoreRank.B };
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
score.Accuracy = 0.85;
|
||||||
|
score.Rank = ScoreRank.B;
|
||||||
|
|
||||||
addPanelStep(score);
|
addPanelStep(score);
|
||||||
}
|
}
|
||||||
@ -41,7 +47,9 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestARank()
|
public void TestARank()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo) { Accuracy = 0.925, Rank = ScoreRank.A };
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
score.Accuracy = 0.925;
|
||||||
|
score.Rank = ScoreRank.A;
|
||||||
|
|
||||||
addPanelStep(score);
|
addPanelStep(score);
|
||||||
}
|
}
|
||||||
@ -49,7 +57,9 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestSRank()
|
public void TestSRank()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo) { Accuracy = 0.975, Rank = ScoreRank.S };
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
score.Accuracy = 0.975;
|
||||||
|
score.Rank = ScoreRank.S;
|
||||||
|
|
||||||
addPanelStep(score);
|
addPanelStep(score);
|
||||||
}
|
}
|
||||||
@ -57,7 +67,9 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestAlmostSSRank()
|
public void TestAlmostSSRank()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo) { Accuracy = 0.9999, Rank = ScoreRank.S };
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
score.Accuracy = 0.9999;
|
||||||
|
score.Rank = ScoreRank.S;
|
||||||
|
|
||||||
addPanelStep(score);
|
addPanelStep(score);
|
||||||
}
|
}
|
||||||
@ -65,7 +77,9 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestSSRank()
|
public void TestSSRank()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo) { Accuracy = 1, Rank = ScoreRank.X };
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
score.Accuracy = 1;
|
||||||
|
score.Rank = ScoreRank.X;
|
||||||
|
|
||||||
addPanelStep(score);
|
addPanelStep(score);
|
||||||
}
|
}
|
||||||
@ -73,7 +87,9 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestAllHitResults()
|
public void TestAllHitResults()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo) { Statistics = { [HitResult.Perfect] = 350, [HitResult.Ok] = 200 } };
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
score.Statistics[HitResult.Perfect] = 350;
|
||||||
|
score.Statistics[HitResult.Ok] = 200;
|
||||||
|
|
||||||
addPanelStep(score);
|
addPanelStep(score);
|
||||||
}
|
}
|
||||||
@ -81,7 +97,9 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestContractedPanel()
|
public void TestContractedPanel()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo) { Accuracy = 0.925, Rank = ScoreRank.A };
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
score.Accuracy = 0.925;
|
||||||
|
score.Rank = ScoreRank.A;
|
||||||
|
|
||||||
addPanelStep(score, PanelState.Contracted);
|
addPanelStep(score, PanelState.Contracted);
|
||||||
}
|
}
|
||||||
@ -89,7 +107,9 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestExpandAndContract()
|
public void TestExpandAndContract()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo) { Accuracy = 0.925, Rank = ScoreRank.A };
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
score.Accuracy = 0.925;
|
||||||
|
score.Rank = ScoreRank.A;
|
||||||
|
|
||||||
addPanelStep(score, PanelState.Contracted);
|
addPanelStep(score, PanelState.Contracted);
|
||||||
AddWaitStep("wait for transition", 10);
|
AddWaitStep("wait for transition", 10);
|
||||||
|
@ -7,9 +7,9 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Rulesets.Osu;
|
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Ranking
|
namespace osu.Game.Tests.Visual.Ranking
|
||||||
@ -29,14 +29,14 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
{
|
{
|
||||||
createListStep(() => new ScorePanelList
|
createListStep(() => new ScorePanelList
|
||||||
{
|
{
|
||||||
SelectedScore = { Value = new TestScoreInfo(new OsuRuleset().RulesetInfo) }
|
SelectedScore = { Value = TestResources.CreateTestScoreInfo() }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestAddPanelAfterSelectingScore()
|
public void TestAddPanelAfterSelectingScore()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo);
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
|
||||||
createListStep(() => new ScorePanelList
|
createListStep(() => new ScorePanelList
|
||||||
{
|
{
|
||||||
@ -52,7 +52,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestAddPanelBeforeSelectingScore()
|
public void TestAddPanelBeforeSelectingScore()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo);
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
|
||||||
createListStep(() => new ScorePanelList());
|
createListStep(() => new ScorePanelList());
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
AddStep("add many scores", () =>
|
AddStep("add many scores", () =>
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 20; i++)
|
for (int i = 0; i < 20; i++)
|
||||||
list.AddScore(new TestScoreInfo(new OsuRuleset().RulesetInfo));
|
list.AddScore(TestResources.CreateTestScoreInfo());
|
||||||
});
|
});
|
||||||
|
|
||||||
assertFirstPanelCentred();
|
assertFirstPanelCentred();
|
||||||
@ -84,7 +84,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestAddManyScoresAfterExpandedPanel()
|
public void TestAddManyScoresAfterExpandedPanel()
|
||||||
{
|
{
|
||||||
var initialScore = new TestScoreInfo(new OsuRuleset().RulesetInfo);
|
var initialScore = TestResources.CreateTestScoreInfo();
|
||||||
|
|
||||||
createListStep(() => new ScorePanelList());
|
createListStep(() => new ScorePanelList());
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
AddStep("add many scores", () =>
|
AddStep("add many scores", () =>
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 20; i++)
|
for (int i = 0; i < 20; i++)
|
||||||
list.AddScore(new TestScoreInfo(new OsuRuleset().RulesetInfo) { TotalScore = initialScore.TotalScore - i - 1 });
|
list.AddScore(createScoreForTotalScore(initialScore.TotalScore - i - 1));
|
||||||
});
|
});
|
||||||
|
|
||||||
assertScoreState(initialScore, true);
|
assertScoreState(initialScore, true);
|
||||||
@ -107,7 +107,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestAddManyScoresBeforeExpandedPanel()
|
public void TestAddManyScoresBeforeExpandedPanel()
|
||||||
{
|
{
|
||||||
var initialScore = new TestScoreInfo(new OsuRuleset().RulesetInfo);
|
var initialScore = TestResources.CreateTestScoreInfo();
|
||||||
|
|
||||||
createListStep(() => new ScorePanelList());
|
createListStep(() => new ScorePanelList());
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
AddStep("add scores", () =>
|
AddStep("add scores", () =>
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 20; i++)
|
for (int i = 0; i < 20; i++)
|
||||||
list.AddScore(new TestScoreInfo(new OsuRuleset().RulesetInfo) { TotalScore = initialScore.TotalScore + i + 1 });
|
list.AddScore(createScoreForTotalScore(initialScore.TotalScore + i + 1));
|
||||||
});
|
});
|
||||||
|
|
||||||
assertScoreState(initialScore, true);
|
assertScoreState(initialScore, true);
|
||||||
@ -130,7 +130,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestAddManyPanelsOnBothSidesOfExpandedPanel()
|
public void TestAddManyPanelsOnBothSidesOfExpandedPanel()
|
||||||
{
|
{
|
||||||
var initialScore = new TestScoreInfo(new OsuRuleset().RulesetInfo);
|
var initialScore = TestResources.CreateTestScoreInfo();
|
||||||
|
|
||||||
createListStep(() => new ScorePanelList());
|
createListStep(() => new ScorePanelList());
|
||||||
|
|
||||||
@ -143,10 +143,10 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
AddStep("add scores after", () =>
|
AddStep("add scores after", () =>
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 20; i++)
|
for (int i = 0; i < 20; i++)
|
||||||
list.AddScore(new TestScoreInfo(new OsuRuleset().RulesetInfo) { TotalScore = initialScore.TotalScore - i - 1 });
|
list.AddScore(createScoreForTotalScore(initialScore.TotalScore - i - 1));
|
||||||
|
|
||||||
for (int i = 0; i < 20; i++)
|
for (int i = 0; i < 20; i++)
|
||||||
list.AddScore(new TestScoreInfo(new OsuRuleset().RulesetInfo) { TotalScore = initialScore.TotalScore + i + 1 });
|
list.AddScore(createScoreForTotalScore(initialScore.TotalScore + i + 1));
|
||||||
});
|
});
|
||||||
|
|
||||||
assertScoreState(initialScore, true);
|
assertScoreState(initialScore, true);
|
||||||
@ -156,11 +156,11 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestSelectMultipleScores()
|
public void TestSelectMultipleScores()
|
||||||
{
|
{
|
||||||
var firstScore = new TestScoreInfo(new OsuRuleset().RulesetInfo);
|
var firstScore = TestResources.CreateTestScoreInfo();
|
||||||
var secondScore = new TestScoreInfo(new OsuRuleset().RulesetInfo);
|
var secondScore = TestResources.CreateTestScoreInfo();
|
||||||
|
|
||||||
firstScore.User.Username = "A";
|
firstScore.UserString = "A";
|
||||||
secondScore.User.Username = "B";
|
secondScore.UserString = "B";
|
||||||
|
|
||||||
createListStep(() => new ScorePanelList());
|
createListStep(() => new ScorePanelList());
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestAddScoreImmediately()
|
public void TestAddScoreImmediately()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo);
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
|
||||||
createListStep(() =>
|
createListStep(() =>
|
||||||
{
|
{
|
||||||
@ -206,9 +206,14 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestKeyboardNavigation()
|
public void TestKeyboardNavigation()
|
||||||
{
|
{
|
||||||
var lowestScore = new TestScoreInfo(new OsuRuleset().RulesetInfo) { MaxCombo = 100 };
|
var lowestScore = TestResources.CreateTestScoreInfo();
|
||||||
var middleScore = new TestScoreInfo(new OsuRuleset().RulesetInfo) { MaxCombo = 200 };
|
lowestScore.MaxCombo = 100;
|
||||||
var highestScore = new TestScoreInfo(new OsuRuleset().RulesetInfo) { MaxCombo = 300 };
|
|
||||||
|
var middleScore = TestResources.CreateTestScoreInfo();
|
||||||
|
middleScore.MaxCombo = 200;
|
||||||
|
|
||||||
|
var highestScore = TestResources.CreateTestScoreInfo();
|
||||||
|
highestScore.MaxCombo = 300;
|
||||||
|
|
||||||
createListStep(() => new ScorePanelList());
|
createListStep(() => new ScorePanelList());
|
||||||
|
|
||||||
@ -270,6 +275,13 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
assertExpandedPanelCentred();
|
assertExpandedPanelCentred();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ScoreInfo createScoreForTotalScore(long totalScore)
|
||||||
|
{
|
||||||
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
|
score.TotalScore = totalScore;
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
private void createListStep(Func<ScorePanelList> creationFunc)
|
private void createListStep(Func<ScorePanelList> creationFunc)
|
||||||
{
|
{
|
||||||
AddStep("create list", () => Child = list = creationFunc().With(d =>
|
AddStep("create list", () => Child = list = creationFunc().With(d =>
|
||||||
|
@ -6,11 +6,11 @@ using System.Collections.Generic;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Osu;
|
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Ranking.Statistics;
|
using osu.Game.Screens.Ranking.Statistics;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Ranking
|
namespace osu.Game.Tests.Visual.Ranking
|
||||||
@ -20,10 +20,8 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestScoreWithTimeStatistics()
|
public void TestScoreWithTimeStatistics()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo)
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
{
|
score.HitEvents = TestSceneHitEventTimingDistributionGraph.CreateDistributedHitEvents();
|
||||||
HitEvents = TestSceneHitEventTimingDistributionGraph.CreateDistributedHitEvents()
|
|
||||||
};
|
|
||||||
|
|
||||||
loadPanel(score);
|
loadPanel(score);
|
||||||
}
|
}
|
||||||
@ -31,10 +29,8 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestScoreWithPositionStatistics()
|
public void TestScoreWithPositionStatistics()
|
||||||
{
|
{
|
||||||
var score = new TestScoreInfo(new OsuRuleset().RulesetInfo)
|
var score = TestResources.CreateTestScoreInfo();
|
||||||
{
|
score.HitEvents = createPositionDistributedHitEvents();
|
||||||
HitEvents = createPositionDistributedHitEvents()
|
|
||||||
};
|
|
||||||
|
|
||||||
loadPanel(score);
|
loadPanel(score);
|
||||||
}
|
}
|
||||||
@ -42,7 +38,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestScoreWithoutStatistics()
|
public void TestScoreWithoutStatistics()
|
||||||
{
|
{
|
||||||
loadPanel(new TestScoreInfo(new OsuRuleset().RulesetInfo));
|
loadPanel(TestResources.CreateTestScoreInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -835,12 +835,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
// this beatmap change should be overridden by the present.
|
// this beatmap change should be overridden by the present.
|
||||||
Beatmap.Value = manager.GetWorkingBeatmap(getSwitchBeatmap());
|
Beatmap.Value = manager.GetWorkingBeatmap(getSwitchBeatmap());
|
||||||
|
|
||||||
songSelect.PresentScore(new ScoreInfo
|
songSelect.PresentScore(TestResources.CreateTestScoreInfo(getPresentBeatmap()));
|
||||||
{
|
|
||||||
User = new APIUser { Username = "woo" },
|
|
||||||
BeatmapInfo = getPresentBeatmap(),
|
|
||||||
Ruleset = getPresentBeatmap().Ruleset
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for results screen presented", () => !songSelect.IsCurrentScreen());
|
AddUntilStep("wait for results screen presented", () => !songSelect.IsCurrentScreen());
|
||||||
|
@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
var score = new ScoreInfo
|
var score = new ScoreInfo
|
||||||
{
|
{
|
||||||
OnlineScoreID = i,
|
OnlineID = i,
|
||||||
BeatmapInfo = beatmapInfo,
|
BeatmapInfo = beatmapInfo,
|
||||||
BeatmapInfoID = beatmapInfo.ID,
|
BeatmapInfoID = beatmapInfo.ID,
|
||||||
Accuracy = RNG.NextDouble(),
|
Accuracy = RNG.NextDouble(),
|
||||||
@ -163,7 +163,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for fetch", () => leaderboard.Scores != null);
|
AddUntilStep("wait for fetch", () => leaderboard.Scores != null);
|
||||||
AddUntilStep("score removed from leaderboard", () => leaderboard.Scores.All(s => s.OnlineScoreID != scoreBeingDeleted.OnlineScoreID));
|
AddUntilStep("score removed from leaderboard", () => leaderboard.Scores.All(s => s.OnlineID != scoreBeingDeleted.OnlineID));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -171,7 +171,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
AddStep("delete top score", () => scoreManager.Delete(importedScores[0]));
|
AddStep("delete top score", () => scoreManager.Delete(importedScores[0]));
|
||||||
AddUntilStep("wait for fetch", () => leaderboard.Scores != null);
|
AddUntilStep("wait for fetch", () => leaderboard.Scores != null);
|
||||||
AddUntilStep("score removed from leaderboard", () => leaderboard.Scores.All(s => s.OnlineScoreID != importedScores[0].OnlineScoreID));
|
AddUntilStep("score removed from leaderboard", () => leaderboard.Scores.All(s => s.OnlineID != importedScores[0].OnlineID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ namespace osu.Game.Database
|
|||||||
|
|
||||||
modelBuilder.Entity<BeatmapInfo>().HasOne(b => b.BaseDifficulty);
|
modelBuilder.Entity<BeatmapInfo>().HasOne(b => b.BaseDifficulty);
|
||||||
|
|
||||||
modelBuilder.Entity<ScoreInfo>().HasIndex(b => b.OnlineScoreID).IsUnique();
|
modelBuilder.Entity<ScoreInfo>().HasIndex(b => b.OnlineID).IsUnique();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class OsuDbLoggerFactory : ILoggerFactory
|
private class OsuDbLoggerFactory : ILoggerFactory
|
||||||
|
@ -104,6 +104,14 @@ namespace osu.Game.Extensions
|
|||||||
/// <returns>Whether online IDs match. If either instance is missing an online ID, this will return false.</returns>
|
/// <returns>Whether online IDs match. If either instance is missing an online ID, this will return false.</returns>
|
||||||
public static bool MatchesOnlineID(this APIUser? instance, APIUser? other) => matchesOnlineID(instance, other);
|
public static bool MatchesOnlineID(this APIUser? instance, APIUser? other) => matchesOnlineID(instance, other);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the online ID of two <see cref="IScoreInfo"/>s match.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">The instance to compare.</param>
|
||||||
|
/// <param name="other">The other instance to compare against.</param>
|
||||||
|
/// <returns>Whether online IDs match. If either instance is missing an online ID, this will return false.</returns>
|
||||||
|
public static bool MatchesOnlineID(this IScoreInfo? instance, IScoreInfo? other) => matchesOnlineID(instance, other);
|
||||||
|
|
||||||
private static bool matchesOnlineID(this IHasOnlineID<long>? instance, IHasOnlineID<long>? other)
|
private static bool matchesOnlineID(this IHasOnlineID<long>? instance, IHasOnlineID<long>? other)
|
||||||
{
|
{
|
||||||
if (instance == null || other == null)
|
if (instance == null || other == null)
|
||||||
|
@ -81,20 +81,37 @@ namespace osu.Game.Input
|
|||||||
// compare counts in database vs defaults for each action type.
|
// compare counts in database vs defaults for each action type.
|
||||||
foreach (var defaultsForAction in defaults.GroupBy(k => k.Action))
|
foreach (var defaultsForAction in defaults.GroupBy(k => k.Action))
|
||||||
{
|
{
|
||||||
// avoid performing redundant queries when the database is empty and needs to be re-filled.
|
IEnumerable<RealmKeyBinding> existing = existingBindings.Where(k =>
|
||||||
int existingCount = existingBindings.Count(k => k.RulesetName == rulesetName && k.Variant == variant && k.ActionInt == (int)defaultsForAction.Key);
|
k.RulesetName == rulesetName
|
||||||
|
&& k.Variant == variant
|
||||||
|
&& k.ActionInt == (int)defaultsForAction.Key);
|
||||||
|
|
||||||
if (defaultsForAction.Count() <= existingCount)
|
int defaultsCount = defaultsForAction.Count();
|
||||||
continue;
|
int existingCount = existing.Count();
|
||||||
|
|
||||||
// insert any defaults which are missing.
|
if (defaultsCount > existingCount)
|
||||||
realm.Add(defaultsForAction.Skip(existingCount).Select(k => new RealmKeyBinding
|
|
||||||
{
|
{
|
||||||
KeyCombinationString = k.KeyCombination.ToString(),
|
// insert any defaults which are missing.
|
||||||
ActionInt = (int)k.Action,
|
realm.Add(defaultsForAction.Skip(existingCount).Select(k => new RealmKeyBinding
|
||||||
RulesetName = rulesetName,
|
{
|
||||||
Variant = variant
|
KeyCombinationString = k.KeyCombination.ToString(),
|
||||||
}));
|
ActionInt = (int)k.Action,
|
||||||
|
RulesetName = rulesetName,
|
||||||
|
Variant = variant
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
else if (defaultsCount < existingCount)
|
||||||
|
{
|
||||||
|
// generally this shouldn't happen, but if the user has more key bindings for an action than we expect,
|
||||||
|
// remove the last entries until the count matches for sanity.
|
||||||
|
foreach (var k in existing.TakeLast(existingCount - defaultsCount).ToArray())
|
||||||
|
{
|
||||||
|
realm.Remove(k);
|
||||||
|
|
||||||
|
// Remove from the local flattened/cached list so future lookups don't query now deleted rows.
|
||||||
|
existingBindings.Remove(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ using osu.Game.Rulesets;
|
|||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
namespace osu.Game.Online.API.Requests
|
||||||
{
|
{
|
||||||
public class GetUserScoresRequest : PaginatedAPIRequest<List<APIScoreInfo>>
|
public class GetUserScoresRequest : PaginatedAPIRequest<List<APIScore>>
|
||||||
{
|
{
|
||||||
private readonly long userId;
|
private readonly long userId;
|
||||||
private readonly ScoreType type;
|
private readonly ScoreType type;
|
||||||
|
@ -13,10 +13,11 @@ using osu.Game.Rulesets;
|
|||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Scoring.Legacy;
|
using osu.Game.Scoring.Legacy;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests.Responses
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
{
|
{
|
||||||
public class APIScoreInfo : IScoreInfo
|
public class APIScore : IScoreInfo
|
||||||
{
|
{
|
||||||
[JsonProperty(@"score")]
|
[JsonProperty(@"score")]
|
||||||
public long TotalScore { get; set; }
|
public long TotalScore { get; set; }
|
||||||
@ -101,7 +102,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
BeatmapInfo = beatmap,
|
BeatmapInfo = beatmap,
|
||||||
User = User,
|
User = User,
|
||||||
Accuracy = Accuracy,
|
Accuracy = Accuracy,
|
||||||
OnlineScoreID = OnlineID,
|
OnlineID = OnlineID,
|
||||||
Date = Date,
|
Date = Date,
|
||||||
PP = PP,
|
PP = PP,
|
||||||
RulesetID = RulesetID,
|
RulesetID = RulesetID,
|
||||||
@ -150,6 +151,11 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
public IRulesetInfo Ruleset => new RulesetInfo { OnlineID = RulesetID };
|
public IRulesetInfo Ruleset => new RulesetInfo { OnlineID = RulesetID };
|
||||||
IEnumerable<INamedFileUsage> IHasNamedFiles.Files => throw new NotImplementedException();
|
IEnumerable<INamedFileUsage> IHasNamedFiles.Files => throw new NotImplementedException();
|
||||||
|
|
||||||
|
#region Implementation of IScoreInfo
|
||||||
|
|
||||||
IBeatmapInfo IScoreInfo.Beatmap => Beatmap;
|
IBeatmapInfo IScoreInfo.Beatmap => Beatmap;
|
||||||
|
IUser IScoreInfo.User => User;
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
public int? Position;
|
public int? Position;
|
||||||
|
|
||||||
[JsonProperty(@"score")]
|
[JsonProperty(@"score")]
|
||||||
public APIScoreInfo Score;
|
public APIScore Score;
|
||||||
|
|
||||||
public ScoreInfo CreateScoreInfo(RulesetStore rulesets, BeatmapInfo beatmap = null)
|
public ScoreInfo CreateScoreInfo(RulesetStore rulesets, BeatmapInfo beatmap = null)
|
||||||
{
|
{
|
||||||
|
@ -9,7 +9,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
public class APIScoresCollection
|
public class APIScoresCollection
|
||||||
{
|
{
|
||||||
[JsonProperty(@"scores")]
|
[JsonProperty(@"scores")]
|
||||||
public List<APIScoreInfo> Scores;
|
public List<APIScore> Scores;
|
||||||
|
|
||||||
[JsonProperty(@"userScore")]
|
[JsonProperty(@"userScore")]
|
||||||
public APIScoreWithPosition UserScore;
|
public APIScoreWithPosition UserScore;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -120,16 +120,21 @@ namespace osu.Game.Online.Chat
|
|||||||
|
|
||||||
private void checkForMentions(Channel channel, Message message)
|
private void checkForMentions(Channel channel, Message message)
|
||||||
{
|
{
|
||||||
if (!notifyOnUsername.Value || !checkContainsUsername(message.Content, localUser.Value.Username)) return;
|
if (!notifyOnUsername.Value || !CheckContainsUsername(message.Content, localUser.Value.Username)) return;
|
||||||
|
|
||||||
notifications.Post(new MentionNotification(message.Sender.Username, channel));
|
notifications.Post(new MentionNotification(message.Sender.Username, channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if <paramref name="message"/> contains <paramref name="username"/>.
|
/// Checks if <paramref name="message"/> mentions <paramref name="username"/>.
|
||||||
/// This will match against the case where underscores are used instead of spaces (which is how osu-stable handles usernames with spaces).
|
/// This will match against the case where underscores are used instead of spaces (which is how osu-stable handles usernames with spaces).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static bool checkContainsUsername(string message, string username) => message.Contains(username, StringComparison.OrdinalIgnoreCase) || message.Contains(username.Replace(' ', '_'), StringComparison.OrdinalIgnoreCase);
|
public static bool CheckContainsUsername(string message, string username)
|
||||||
|
{
|
||||||
|
string fullName = Regex.Escape(username);
|
||||||
|
string underscoreName = Regex.Escape(username.Replace(' ', '_'));
|
||||||
|
return Regex.IsMatch(message, $@"(^|\W)({fullName}|{underscoreName})($|\W)", RegexOptions.IgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
public class PrivateMessageNotification : OpenChannelNotification
|
public class PrivateMessageNotification : OpenChannelNotification
|
||||||
{
|
{
|
||||||
|
@ -111,7 +111,7 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
background = new Box
|
background = new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = user.Id == api.LocalUser.Value.Id && allowHighlight ? colour.Green : Color4.Black,
|
Colour = user.OnlineID == api.LocalUser.Value.Id && allowHighlight ? colour.Green : Color4.Black,
|
||||||
Alpha = background_alpha,
|
Alpha = background_alpha,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -95,8 +95,6 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
protected readonly BindableList<int> PlayingUserIds = new BindableList<int>();
|
protected readonly BindableList<int> PlayingUserIds = new BindableList<int>();
|
||||||
|
|
||||||
public readonly Bindable<PlaylistItem?> CurrentMatchPlayingItem = new Bindable<PlaylistItem?>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="MultiplayerRoomUser"/> corresponding to the local player, if available.
|
/// The <see cref="MultiplayerRoomUser"/> corresponding to the local player, if available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -162,9 +160,6 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
var joinedRoom = await JoinRoom(room.RoomID.Value.Value, password ?? room.Password.Value).ConfigureAwait(false);
|
var joinedRoom = await JoinRoom(room.RoomID.Value.Value, password ?? room.Password.Value).ConfigureAwait(false);
|
||||||
Debug.Assert(joinedRoom != null);
|
Debug.Assert(joinedRoom != null);
|
||||||
|
|
||||||
// Populate playlist items.
|
|
||||||
var playlistItems = await Task.WhenAll(joinedRoom.Playlist.Select(item => createPlaylistItem(item, item.ID == joinedRoom.Settings.PlaylistItemId))).ConfigureAwait(false);
|
|
||||||
|
|
||||||
// Populate users.
|
// Populate users.
|
||||||
Debug.Assert(joinedRoom.Users != null);
|
Debug.Assert(joinedRoom.Users != null);
|
||||||
await Task.WhenAll(joinedRoom.Users.Select(PopulateUser)).ConfigureAwait(false);
|
await Task.WhenAll(joinedRoom.Users.Select(PopulateUser)).ConfigureAwait(false);
|
||||||
@ -176,7 +171,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
APIRoom = room;
|
APIRoom = room;
|
||||||
|
|
||||||
APIRoom.Playlist.Clear();
|
APIRoom.Playlist.Clear();
|
||||||
APIRoom.Playlist.AddRange(playlistItems);
|
APIRoom.Playlist.AddRange(joinedRoom.Playlist.Select(createPlaylistItem));
|
||||||
|
|
||||||
Debug.Assert(LocalUser != null);
|
Debug.Assert(LocalUser != null);
|
||||||
addUserToAPIRoom(LocalUser);
|
addUserToAPIRoom(LocalUser);
|
||||||
@ -219,7 +214,6 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
{
|
{
|
||||||
APIRoom = null;
|
APIRoom = null;
|
||||||
Room = null;
|
Room = null;
|
||||||
CurrentMatchPlayingItem.Value = null;
|
|
||||||
PlayingUserIds.Clear();
|
PlayingUserIds.Clear();
|
||||||
|
|
||||||
RoomUpdated?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
@ -477,28 +471,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
Debug.Assert(APIRoom != null);
|
Debug.Assert(APIRoom != null);
|
||||||
Debug.Assert(Room != null);
|
Debug.Assert(Room != null);
|
||||||
|
|
||||||
Scheduler.Add(() =>
|
Scheduler.Add(() => updateLocalRoomSettings(newSettings));
|
||||||
{
|
|
||||||
// ensure the new selected item is populated immediately.
|
|
||||||
var playlistItem = APIRoom.Playlist.Single(p => p.ID == newSettings.PlaylistItemId);
|
|
||||||
|
|
||||||
if (playlistItem != null)
|
|
||||||
{
|
|
||||||
GetAPIBeatmap(playlistItem.BeatmapID).ContinueWith(b =>
|
|
||||||
{
|
|
||||||
// Should be called outside of the `Scheduler` logic (and specifically accessing `Exception`) to suppress an exception from firing outwards.
|
|
||||||
bool success = b.Exception == null;
|
|
||||||
|
|
||||||
Scheduler.Add(() =>
|
|
||||||
{
|
|
||||||
if (success)
|
|
||||||
playlistItem.Beatmap.Value = b.Result;
|
|
||||||
|
|
||||||
updateLocalRoomSettings(newSettings);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -653,12 +626,10 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PlaylistItemAdded(MultiplayerPlaylistItem item)
|
public Task PlaylistItemAdded(MultiplayerPlaylistItem item)
|
||||||
{
|
{
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
var playlistItem = await createPlaylistItem(item, true).ConfigureAwait(false);
|
|
||||||
|
|
||||||
Scheduler.Add(() =>
|
Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
@ -668,11 +639,13 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
Debug.Assert(APIRoom != null);
|
Debug.Assert(APIRoom != null);
|
||||||
|
|
||||||
Room.Playlist.Add(item);
|
Room.Playlist.Add(item);
|
||||||
APIRoom.Playlist.Add(playlistItem);
|
APIRoom.Playlist.Add(createPlaylistItem(item));
|
||||||
|
|
||||||
ItemAdded?.Invoke(item);
|
ItemAdded?.Invoke(item);
|
||||||
RoomUpdated?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task PlaylistItemRemoved(long playlistItemId)
|
public Task PlaylistItemRemoved(long playlistItemId)
|
||||||
@ -697,12 +670,10 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PlaylistItemChanged(MultiplayerPlaylistItem item)
|
public Task PlaylistItemChanged(MultiplayerPlaylistItem item)
|
||||||
{
|
{
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
var playlistItem = await createPlaylistItem(item, true).ConfigureAwait(false);
|
|
||||||
|
|
||||||
Scheduler.Add(() =>
|
Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
@ -715,15 +686,13 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
int existingIndex = APIRoom.Playlist.IndexOf(APIRoom.Playlist.Single(existing => existing.ID == item.ID));
|
int existingIndex = APIRoom.Playlist.IndexOf(APIRoom.Playlist.Single(existing => existing.ID == item.ID));
|
||||||
APIRoom.Playlist.RemoveAt(existingIndex);
|
APIRoom.Playlist.RemoveAt(existingIndex);
|
||||||
APIRoom.Playlist.Insert(existingIndex, playlistItem);
|
APIRoom.Playlist.Insert(existingIndex, createPlaylistItem(item));
|
||||||
|
|
||||||
// If the currently-selected item was the one that got replaced, update the selected item to the new one.
|
|
||||||
if (CurrentMatchPlayingItem.Value?.ID == playlistItem.ID)
|
|
||||||
CurrentMatchPlayingItem.Value = playlistItem;
|
|
||||||
|
|
||||||
ItemChanged?.Invoke(item);
|
ItemChanged?.Invoke(item);
|
||||||
RoomUpdated?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -752,12 +721,11 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
APIRoom.Password.Value = Room.Settings.Password;
|
APIRoom.Password.Value = Room.Settings.Password;
|
||||||
APIRoom.Type.Value = Room.Settings.MatchType;
|
APIRoom.Type.Value = Room.Settings.MatchType;
|
||||||
APIRoom.QueueMode.Value = Room.Settings.QueueMode;
|
APIRoom.QueueMode.Value = Room.Settings.QueueMode;
|
||||||
RoomUpdated?.Invoke();
|
|
||||||
|
|
||||||
CurrentMatchPlayingItem.Value = APIRoom.Playlist.SingleOrDefault(p => p.ID == settings.PlaylistItemId);
|
RoomUpdated?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<PlaylistItem> createPlaylistItem(MultiplayerPlaylistItem item, bool populateBeatmapImmediately)
|
private PlaylistItem createPlaylistItem(MultiplayerPlaylistItem item)
|
||||||
{
|
{
|
||||||
var ruleset = Rulesets.GetRuleset(item.RulesetID);
|
var ruleset = Rulesets.GetRuleset(item.RulesetID);
|
||||||
|
|
||||||
@ -779,9 +747,6 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
playlistItem.RequiredMods.AddRange(item.RequiredMods.Select(m => m.ToMod(rulesetInstance)));
|
playlistItem.RequiredMods.AddRange(item.RequiredMods.Select(m => m.ToMod(rulesetInstance)));
|
||||||
playlistItem.AllowedMods.AddRange(item.AllowedMods.Select(m => m.ToMod(rulesetInstance)));
|
playlistItem.AllowedMods.AddRange(item.AllowedMods.Select(m => m.ToMod(rulesetInstance)));
|
||||||
|
|
||||||
if (populateBeatmapImmediately)
|
|
||||||
playlistItem.Beatmap.Value = await GetAPIBeatmap(item.BeatmapID).ConfigureAwait(false);
|
|
||||||
|
|
||||||
return playlistItem;
|
return playlistItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,7 +756,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// <param name="beatmapId">The beatmap ID.</param>
|
/// <param name="beatmapId">The beatmap ID.</param>
|
||||||
/// <param name="cancellationToken">A token to cancel the request.</param>
|
/// <param name="cancellationToken">A token to cancel the request.</param>
|
||||||
/// <returns>The <see cref="APIBeatmap"/> retrieval task.</returns>
|
/// <returns>The <see cref="APIBeatmap"/> retrieval task.</returns>
|
||||||
protected abstract Task<APIBeatmap> GetAPIBeatmap(int beatmapId, CancellationToken cancellationToken = default);
|
public abstract Task<APIBeatmap> GetAPIBeatmap(int beatmapId, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For the provided user ID, update whether the user is included in <see cref="CurrentMatchPlayingUserIds"/>.
|
/// For the provided user ID, update whether the user is included in <see cref="CurrentMatchPlayingUserIds"/>.
|
||||||
|
@ -178,7 +178,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
return connection.InvokeAsync(nameof(IMultiplayerServer.RemovePlaylistItem), playlistItemId);
|
return connection.InvokeAsync(nameof(IMultiplayerServer.RemovePlaylistItem), playlistItemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Task<APIBeatmap> GetAPIBeatmap(int beatmapId, CancellationToken cancellationToken = default)
|
public override Task<APIBeatmap> GetAPIBeatmap(int beatmapId, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return beatmapLookupCache.GetBeatmapAsync(beatmapId, cancellationToken);
|
return beatmapLookupCache.GetBeatmapAsync(beatmapId, cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ namespace osu.Game.Online.Rooms
|
|||||||
|
|
||||||
var scoreInfo = new ScoreInfo
|
var scoreInfo = new ScoreInfo
|
||||||
{
|
{
|
||||||
OnlineScoreID = ID,
|
OnlineID = ID,
|
||||||
TotalScore = TotalScore,
|
TotalScore = TotalScore,
|
||||||
MaxCombo = MaxCombo,
|
MaxCombo = MaxCombo,
|
||||||
BeatmapInfo = beatmap,
|
BeatmapInfo = beatmap,
|
||||||
|
@ -40,6 +40,11 @@ namespace osu.Game.Online.Rooms
|
|||||||
|
|
||||||
private BeatmapDownloadTracker downloadTracker;
|
private BeatmapDownloadTracker downloadTracker;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The beatmap matching the required hash (and providing a final <see cref="BeatmapAvailability.LocallyAvailable"/> state).
|
||||||
|
/// </summary>
|
||||||
|
private BeatmapInfo matchingHash;
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
@ -71,13 +76,34 @@ namespace osu.Game.Online.Rooms
|
|||||||
progressUpdate = Scheduler.AddDelayed(updateAvailability, progressUpdate == null ? 0 : 500);
|
progressUpdate = Scheduler.AddDelayed(updateAvailability, progressUpdate == null ? 0 : 500);
|
||||||
}, true);
|
}, true);
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
// These events are needed for a fringe case where a modified/altered beatmap is imported with matching OnlineIDs.
|
||||||
|
// During the import process this will cause the existing beatmap set to be silently deleted and replaced with the new one.
|
||||||
|
// This is not exposed to us via `BeatmapDownloadTracker` so we have to take it into our own hands (as we care about the hash matching).
|
||||||
|
beatmapManager.ItemUpdated += itemUpdated;
|
||||||
|
beatmapManager.ItemRemoved += itemRemoved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void itemUpdated(BeatmapSetInfo item) => Schedule(() =>
|
||||||
|
{
|
||||||
|
if (matchingHash?.BeatmapSet.ID == item.ID || SelectedItem.Value?.Beatmap.Value.BeatmapSet?.OnlineID == item.OnlineID)
|
||||||
|
updateAvailability();
|
||||||
|
});
|
||||||
|
|
||||||
|
private void itemRemoved(BeatmapSetInfo item) => Schedule(() =>
|
||||||
|
{
|
||||||
|
if (matchingHash?.BeatmapSet.ID == item.ID)
|
||||||
|
updateAvailability();
|
||||||
|
});
|
||||||
|
|
||||||
private void updateAvailability()
|
private void updateAvailability()
|
||||||
{
|
{
|
||||||
if (downloadTracker == null)
|
if (downloadTracker == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// will be repopulated below if still valid.
|
||||||
|
matchingHash = null;
|
||||||
|
|
||||||
switch (downloadTracker.State.Value)
|
switch (downloadTracker.State.Value)
|
||||||
{
|
{
|
||||||
case DownloadState.NotDownloaded:
|
case DownloadState.NotDownloaded:
|
||||||
@ -93,7 +119,9 @@ namespace osu.Game.Online.Rooms
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DownloadState.LocallyAvailable:
|
case DownloadState.LocallyAvailable:
|
||||||
bool hashMatches = checkHashValidity();
|
matchingHash = findMatchingHash();
|
||||||
|
|
||||||
|
bool hashMatches = matchingHash != null;
|
||||||
|
|
||||||
availability.Value = hashMatches ? BeatmapAvailability.LocallyAvailable() : BeatmapAvailability.NotDownloaded();
|
availability.Value = hashMatches ? BeatmapAvailability.LocallyAvailable() : BeatmapAvailability.NotDownloaded();
|
||||||
|
|
||||||
@ -108,12 +136,23 @@ namespace osu.Game.Online.Rooms
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool checkHashValidity()
|
private BeatmapInfo findMatchingHash()
|
||||||
{
|
{
|
||||||
int onlineId = SelectedItem.Value.Beatmap.Value.OnlineID;
|
int onlineId = SelectedItem.Value.Beatmap.Value.OnlineID;
|
||||||
string checksum = SelectedItem.Value.Beatmap.Value.MD5Hash;
|
string checksum = SelectedItem.Value.Beatmap.Value.MD5Hash;
|
||||||
|
|
||||||
return beatmapManager.QueryBeatmap(b => b.OnlineID == onlineId && b.MD5Hash == checksum && !b.BeatmapSet.DeletePending) != null;
|
return beatmapManager.QueryBeatmap(b => b.OnlineID == onlineId && b.MD5Hash == checksum && !b.BeatmapSet.DeletePending);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
if (beatmapManager != null)
|
||||||
|
{
|
||||||
|
beatmapManager.ItemUpdated -= itemUpdated;
|
||||||
|
beatmapManager.ItemRemoved -= itemRemoved;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ namespace osu.Game.Online.Rooms
|
|||||||
|
|
||||||
req.ContentType = "application/json";
|
req.ContentType = "application/json";
|
||||||
req.Method = HttpMethod.Put;
|
req.Method = HttpMethod.Put;
|
||||||
|
req.Timeout = 30000;
|
||||||
|
|
||||||
req.AddRaw(JsonConvert.SerializeObject(score, new JsonSerializerSettings
|
req.AddRaw(JsonConvert.SerializeObject(score, new JsonSerializerSettings
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Extensions;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
@ -35,7 +36,7 @@ namespace osu.Game.Online
|
|||||||
var scoreInfo = new ScoreInfo
|
var scoreInfo = new ScoreInfo
|
||||||
{
|
{
|
||||||
ID = TrackedItem.ID,
|
ID = TrackedItem.ID,
|
||||||
OnlineScoreID = TrackedItem.OnlineScoreID
|
OnlineID = TrackedItem.OnlineID
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Manager.IsAvailableLocally(scoreInfo))
|
if (Manager.IsAvailableLocally(scoreInfo))
|
||||||
@ -113,7 +114,7 @@ namespace osu.Game.Online
|
|||||||
UpdateState(DownloadState.NotDownloaded);
|
UpdateState(DownloadState.NotDownloaded);
|
||||||
});
|
});
|
||||||
|
|
||||||
private bool checkEquality(IScoreInfo x, IScoreInfo y) => x.OnlineID == y.OnlineID;
|
private bool checkEquality(IScoreInfo x, IScoreInfo y) => x.MatchesOnlineID(y);
|
||||||
|
|
||||||
#region Disposal
|
#region Disposal
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ namespace osu.Game.Online.Solo
|
|||||||
|
|
||||||
req.ContentType = "application/json";
|
req.ContentType = "application/json";
|
||||||
req.Method = HttpMethod.Put;
|
req.Method = HttpMethod.Put;
|
||||||
|
req.Timeout = 30000;
|
||||||
|
|
||||||
req.AddRaw(JsonConvert.SerializeObject(score, new JsonSerializerSettings
|
req.AddRaw(JsonConvert.SerializeObject(score, new JsonSerializerSettings
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Online.Solo
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A class specifically for sending scores to the API during score submission.
|
/// A class specifically for sending scores to the API during score submission.
|
||||||
/// This is used instead of <see cref="APIScoreInfo"/> due to marginally different serialisation naming requirements.
|
/// This is used instead of <see cref="APIScore"/> due to marginally different serialisation naming requirements.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class SubmittableScore
|
public class SubmittableScore
|
||||||
|
@ -103,7 +103,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
private Container topMostOverlayContent;
|
private Container topMostOverlayContent;
|
||||||
|
|
||||||
private ScalingContainer screenContainer;
|
protected ScalingContainer ScreenContainer { get; private set; }
|
||||||
|
|
||||||
protected Container ScreenOffsetContainer { get; private set; }
|
protected Container ScreenOffsetContainer { get; private set; }
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ namespace osu.Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateBlockingOverlayFade() =>
|
private void updateBlockingOverlayFade() =>
|
||||||
screenContainer.FadeColour(visibleBlockingOverlays.Any() ? OsuColour.Gray(0.5f) : Color4.White, 500, Easing.OutQuint);
|
ScreenContainer.FadeColour(visibleBlockingOverlays.Any() ? OsuColour.Gray(0.5f) : Color4.White, 500, Easing.OutQuint);
|
||||||
|
|
||||||
public void AddBlockingOverlay(OverlayContainer overlay)
|
public void AddBlockingOverlay(OverlayContainer overlay)
|
||||||
{
|
{
|
||||||
@ -487,8 +487,8 @@ namespace osu.Game
|
|||||||
// to ensure all the required data for presenting a replay are present.
|
// to ensure all the required data for presenting a replay are present.
|
||||||
ScoreInfo databasedScoreInfo = null;
|
ScoreInfo databasedScoreInfo = null;
|
||||||
|
|
||||||
if (score.OnlineScoreID != null)
|
if (score.OnlineID > 0)
|
||||||
databasedScoreInfo = ScoreManager.Query(s => s.OnlineScoreID == score.OnlineScoreID);
|
databasedScoreInfo = ScoreManager.Query(s => s.OnlineID == score.OnlineID);
|
||||||
|
|
||||||
databasedScoreInfo ??= ScoreManager.Query(s => s.Hash == score.Hash);
|
databasedScoreInfo ??= ScoreManager.Query(s => s.Hash == score.Hash);
|
||||||
|
|
||||||
@ -698,7 +698,7 @@ namespace osu.Game
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
screenContainer = new ScalingContainer(ScalingMode.ExcludeOverlays)
|
ScreenContainer = new ScalingContainer(ScalingMode.ExcludeOverlays)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -801,7 +801,7 @@ namespace osu.Game
|
|||||||
loadComponentSingleFile(userProfile = new UserProfileOverlay(), overlayContent.Add, true);
|
loadComponentSingleFile(userProfile = new UserProfileOverlay(), overlayContent.Add, true);
|
||||||
loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay(), overlayContent.Add, true);
|
loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay(), overlayContent.Add, true);
|
||||||
loadComponentSingleFile(wikiOverlay = new WikiOverlay(), overlayContent.Add, true);
|
loadComponentSingleFile(wikiOverlay = new WikiOverlay(), overlayContent.Add, true);
|
||||||
loadComponentSingleFile(skinEditor = new SkinEditorOverlay(screenContainer), overlayContent.Add, true);
|
loadComponentSingleFile(skinEditor = new SkinEditorOverlay(ScreenContainer), overlayContent.Add, true);
|
||||||
|
|
||||||
loadComponentSingleFile(new LoginOverlay
|
loadComponentSingleFile(new LoginOverlay
|
||||||
{
|
{
|
||||||
|
@ -94,7 +94,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
|
|
||||||
topScoresContainer.Add(new DrawableTopScore(topScore));
|
topScoresContainer.Add(new DrawableTopScore(topScore));
|
||||||
|
|
||||||
if (userScoreInfo != null && userScoreInfo.OnlineScoreID != topScore.OnlineScoreID)
|
if (userScoreInfo != null && userScoreInfo.OnlineID != topScore.OnlineID)
|
||||||
topScoresContainer.Add(new DrawableTopScore(userScoreInfo, userScore.Position));
|
topScoresContainer.Add(new DrawableTopScore(userScoreInfo, userScore.Position));
|
||||||
}), TaskContinuationOptions.OnlyOnRanToCompletion);
|
}), TaskContinuationOptions.OnlyOnRanToCompletion);
|
||||||
});
|
});
|
||||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
|
|
||||||
private const float performance_background_shear = 0.45f;
|
private const float performance_background_shear = 0.45f;
|
||||||
|
|
||||||
protected readonly APIScoreInfo Score;
|
protected readonly APIScore Score;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; }
|
private OsuColour colours { get; set; }
|
||||||
@ -36,7 +36,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private OverlayColourProvider colourProvider { get; set; }
|
private OverlayColourProvider colourProvider { get; set; }
|
||||||
|
|
||||||
public DrawableProfileScore(APIScoreInfo score)
|
public DrawableProfileScore(APIScore score)
|
||||||
{
|
{
|
||||||
Score = score;
|
Score = score;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
{
|
{
|
||||||
private readonly double weight;
|
private readonly double weight;
|
||||||
|
|
||||||
public DrawableProfileWeightedScore(APIScoreInfo score, double weight)
|
public DrawableProfileWeightedScore(APIScore score, double weight)
|
||||||
: base(score)
|
: base(score)
|
||||||
{
|
{
|
||||||
this.weight = weight;
|
this.weight = weight;
|
||||||
|
@ -15,7 +15,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser;
|
|||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||||
{
|
{
|
||||||
public class PaginatedScoreContainer : PaginatedProfileSubsection<APIScoreInfo>
|
public class PaginatedScoreContainer : PaginatedProfileSubsection<APIScore>
|
||||||
{
|
{
|
||||||
private readonly ScoreType type;
|
private readonly ScoreType type;
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnItemsReceived(List<APIScoreInfo> items)
|
protected override void OnItemsReceived(List<APIScore> items)
|
||||||
{
|
{
|
||||||
if (VisiblePages == 0)
|
if (VisiblePages == 0)
|
||||||
drawableItemIndex = 0;
|
drawableItemIndex = 0;
|
||||||
@ -59,12 +59,12 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
base.OnItemsReceived(items);
|
base.OnItemsReceived(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override APIRequest<List<APIScoreInfo>> CreateRequest() =>
|
protected override APIRequest<List<APIScore>> CreateRequest() =>
|
||||||
new GetUserScoresRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage);
|
new GetUserScoresRequest(User.Value.Id, type, VisiblePages++, ItemsPerPage);
|
||||||
|
|
||||||
private int drawableItemIndex;
|
private int drawableItemIndex;
|
||||||
|
|
||||||
protected override Drawable CreateDrawableItem(APIScoreInfo model)
|
protected override Drawable CreateDrawableItem(APIScore model)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Scoring
|
namespace osu.Game.Scoring
|
||||||
{
|
{
|
||||||
public interface IScoreInfo : IHasOnlineID<long>, IHasNamedFiles
|
public interface IScoreInfo : IHasOnlineID<long>, IHasNamedFiles
|
||||||
{
|
{
|
||||||
APIUser User { get; }
|
IUser User { get; }
|
||||||
|
|
||||||
long TotalScore { get; }
|
long TotalScore { get; }
|
||||||
|
|
||||||
|
@ -80,12 +80,9 @@ namespace osu.Game.Scoring.Legacy
|
|||||||
byte[] compressedReplay = sr.ReadByteArray();
|
byte[] compressedReplay = sr.ReadByteArray();
|
||||||
|
|
||||||
if (version >= 20140721)
|
if (version >= 20140721)
|
||||||
scoreInfo.OnlineScoreID = sr.ReadInt64();
|
scoreInfo.OnlineID = sr.ReadInt64();
|
||||||
else if (version >= 20121008)
|
else if (version >= 20121008)
|
||||||
scoreInfo.OnlineScoreID = sr.ReadInt32();
|
scoreInfo.OnlineID = sr.ReadInt32();
|
||||||
|
|
||||||
if (scoreInfo.OnlineScoreID <= 0)
|
|
||||||
scoreInfo.OnlineScoreID = null;
|
|
||||||
|
|
||||||
if (compressedReplay?.Length > 0)
|
if (compressedReplay?.Length > 0)
|
||||||
{
|
{
|
||||||
|
@ -14,6 +14,7 @@ using osu.Game.Online.API.Requests.Responses;
|
|||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Users;
|
||||||
using osu.Game.Utils;
|
using osu.Game.Utils;
|
||||||
|
|
||||||
namespace osu.Game.Scoring
|
namespace osu.Game.Scoring
|
||||||
@ -136,7 +137,14 @@ namespace osu.Game.Scoring
|
|||||||
[Column("Beatmap")]
|
[Column("Beatmap")]
|
||||||
public BeatmapInfo BeatmapInfo { get; set; }
|
public BeatmapInfo BeatmapInfo { get; set; }
|
||||||
|
|
||||||
public long? OnlineScoreID { get; set; }
|
private long? onlineID;
|
||||||
|
|
||||||
|
[Column("OnlineScoreID")]
|
||||||
|
public long? OnlineID
|
||||||
|
{
|
||||||
|
get => onlineID;
|
||||||
|
set => onlineID = value > 0 ? value : null;
|
||||||
|
}
|
||||||
|
|
||||||
public DateTimeOffset Date { get; set; }
|
public DateTimeOffset Date { get; set; }
|
||||||
|
|
||||||
@ -231,24 +239,18 @@ namespace osu.Game.Scoring
|
|||||||
|
|
||||||
public bool Equals(ScoreInfo other)
|
public bool Equals(ScoreInfo other)
|
||||||
{
|
{
|
||||||
if (other == null)
|
if (ReferenceEquals(this, other)) return true;
|
||||||
return false;
|
if (other == null) return false;
|
||||||
|
|
||||||
if (ID != 0 && other.ID != 0)
|
if (ID != 0 && other.ID != 0)
|
||||||
return ID == other.ID;
|
return ID == other.ID;
|
||||||
|
|
||||||
if (OnlineScoreID.HasValue && other.OnlineScoreID.HasValue)
|
return false;
|
||||||
return OnlineScoreID == other.OnlineScoreID;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Hash) && !string.IsNullOrEmpty(other.Hash))
|
|
||||||
return Hash == other.Hash;
|
|
||||||
|
|
||||||
return ReferenceEquals(this, other);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Implementation of IHasOnlineID
|
#region Implementation of IHasOnlineID
|
||||||
|
|
||||||
public long OnlineID => OnlineScoreID ?? -1;
|
long IHasOnlineID<long>.OnlineID => OnlineID ?? -1;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -256,6 +258,7 @@ namespace osu.Game.Scoring
|
|||||||
|
|
||||||
IBeatmapInfo IScoreInfo.Beatmap => BeatmapInfo;
|
IBeatmapInfo IScoreInfo.Beatmap => BeatmapInfo;
|
||||||
IRulesetInfo IScoreInfo.Ruleset => Ruleset;
|
IRulesetInfo IScoreInfo.Ruleset => Ruleset;
|
||||||
|
IUser IScoreInfo.User => User;
|
||||||
bool IScoreInfo.HasReplay => Files.Any();
|
bool IScoreInfo.HasReplay => Files.Any();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -71,7 +71,7 @@ namespace osu.Game.Scoring
|
|||||||
|
|
||||||
return scores.Select((score, index) => (score, totalScore: totalScores[index]))
|
return scores.Select((score, index) => (score, totalScore: totalScores[index]))
|
||||||
.OrderByDescending(g => g.totalScore)
|
.OrderByDescending(g => g.totalScore)
|
||||||
.ThenBy(g => g.score.OnlineScoreID)
|
.ThenBy(g => g.score.OnlineID)
|
||||||
.Select(g => g.score)
|
.Select(g => g.score)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Extensions;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
|
|
||||||
@ -17,6 +18,6 @@ namespace osu.Game.Scoring
|
|||||||
protected override ArchiveDownloadRequest<IScoreInfo> CreateDownloadRequest(IScoreInfo score, bool minimiseDownload) => new DownloadReplayRequest(score);
|
protected override ArchiveDownloadRequest<IScoreInfo> CreateDownloadRequest(IScoreInfo score, bool minimiseDownload) => new DownloadReplayRequest(score);
|
||||||
|
|
||||||
public override ArchiveDownloadRequest<IScoreInfo> GetExistingDownload(IScoreInfo model)
|
public override ArchiveDownloadRequest<IScoreInfo> GetExistingDownload(IScoreInfo model)
|
||||||
=> CurrentDownloads.Find(r => r.Model.OnlineID == model.OnlineID);
|
=> CurrentDownloads.Find(r => r.Model.MatchesOnlineID(model));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,6 @@ namespace osu.Game.Scoring
|
|||||||
|
|
||||||
protected override bool CheckLocalAvailability(ScoreInfo model, IQueryable<ScoreInfo> items)
|
protected override bool CheckLocalAvailability(ScoreInfo model, IQueryable<ScoreInfo> items)
|
||||||
=> base.CheckLocalAvailability(model, items)
|
=> base.CheckLocalAvailability(model, items)
|
||||||
|| (model.OnlineScoreID != null && items.Any(i => i.OnlineScoreID == model.OnlineScoreID));
|
|| (model.OnlineID > 0 && items.Any(i => i.OnlineID == model.OnlineID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,16 +48,19 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
|
|
||||||
AddInternal(seasonalBackgroundLoader);
|
AddInternal(seasonalBackgroundLoader);
|
||||||
|
|
||||||
user.ValueChanged += _ => Next();
|
user.ValueChanged += _ => Scheduler.AddOnce(loadNextIfRequired);
|
||||||
skin.ValueChanged += _ => Next();
|
skin.ValueChanged += _ => Scheduler.AddOnce(loadNextIfRequired);
|
||||||
mode.ValueChanged += _ => Next();
|
mode.ValueChanged += _ => Scheduler.AddOnce(loadNextIfRequired);
|
||||||
beatmap.ValueChanged += _ => Next();
|
beatmap.ValueChanged += _ => Scheduler.AddOnce(loadNextIfRequired);
|
||||||
introSequence.ValueChanged += _ => Next();
|
introSequence.ValueChanged += _ => Scheduler.AddOnce(loadNextIfRequired);
|
||||||
seasonalBackgroundLoader.SeasonalBackgroundChanged += () => Next();
|
seasonalBackgroundLoader.SeasonalBackgroundChanged += () => Scheduler.AddOnce(loadNextIfRequired);
|
||||||
|
|
||||||
currentDisplay = RNG.Next(0, background_count);
|
currentDisplay = RNG.Next(0, background_count);
|
||||||
|
|
||||||
Next();
|
Next();
|
||||||
|
|
||||||
|
// helper function required for AddOnce usage.
|
||||||
|
void loadNextIfRequired() => Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScheduledDelegate nextTask;
|
private ScheduledDelegate nextTask;
|
||||||
@ -67,7 +70,7 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
/// Request loading the next background.
|
/// Request loading the next background.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Whether a new background was queued for load. May return false if the current background is still valid.</returns>
|
/// <returns>Whether a new background was queued for load. May return false if the current background is still valid.</returns>
|
||||||
public bool Next()
|
public virtual bool Next()
|
||||||
{
|
{
|
||||||
var nextBackground = createBackground();
|
var nextBackground = createBackground();
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -9,6 +10,7 @@ using osu.Framework.Screens;
|
|||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
@ -53,6 +55,14 @@ namespace osu.Game.Screens.Edit
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
// will be restored via lease, see `DisallowExternalBeatmapRulesetChanges`.
|
||||||
|
Mods.Value = Array.Empty<Mod>();
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual Editor CreateEditor() => new Editor(this);
|
protected virtual Editor CreateEditor() => new Editor(this);
|
||||||
|
|
||||||
protected override void LogoArriving(OsuLogo logo, bool resuming)
|
protected override void LogoArriving(OsuLogo logo, bool resuming)
|
||||||
|
@ -7,6 +7,7 @@ using System.Diagnostics;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Development;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
@ -107,6 +108,7 @@ namespace osu.Game.Screens.OnlinePlay.Components
|
|||||||
|
|
||||||
public void AddOrUpdateRoom(Room room)
|
public void AddOrUpdateRoom(Room room)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(ThreadSafety.IsUpdateThread);
|
||||||
Debug.Assert(room.RoomID.Value != null);
|
Debug.Assert(room.RoomID.Value != null);
|
||||||
|
|
||||||
if (ignoredRooms.Contains(room.RoomID.Value.Value))
|
if (ignoredRooms.Contains(room.RoomID.Value.Value))
|
||||||
@ -136,12 +138,16 @@ namespace osu.Game.Screens.OnlinePlay.Components
|
|||||||
|
|
||||||
public void RemoveRoom(Room room)
|
public void RemoveRoom(Room room)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(ThreadSafety.IsUpdateThread);
|
||||||
|
|
||||||
rooms.Remove(room);
|
rooms.Remove(room);
|
||||||
notifyRoomsUpdated();
|
notifyRoomsUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearRooms()
|
public void ClearRooms()
|
||||||
{
|
{
|
||||||
|
Debug.Assert(ThreadSafety.IsUpdateThread);
|
||||||
|
|
||||||
rooms.Clear();
|
rooms.Clear();
|
||||||
notifyRoomsUpdated();
|
notifyRoomsUpdated();
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -24,6 +25,7 @@ using osu.Game.Graphics.Containers;
|
|||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online;
|
using osu.Game.Online;
|
||||||
using osu.Game.Online.Chat;
|
using osu.Game.Online.Chat;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Overlays.BeatmapSet;
|
using osu.Game.Overlays.BeatmapSet;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@ -90,6 +92,10 @@ namespace osu.Game.Screens.OnlinePlay
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private UserLookupCache userLookupCache { get; set; }
|
private UserLookupCache userLookupCache { get; set; }
|
||||||
|
|
||||||
|
[CanBeNull]
|
||||||
|
[Resolved(CanBeNull = true)]
|
||||||
|
private MultiplayerClient multiplayerClient { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private BeatmapLookupCache beatmapLookupCache { get; set; }
|
private BeatmapLookupCache beatmapLookupCache { get; set; }
|
||||||
|
|
||||||
@ -157,7 +163,15 @@ namespace osu.Game.Screens.OnlinePlay
|
|||||||
|
|
||||||
if (Item.Beatmap.Value == null)
|
if (Item.Beatmap.Value == null)
|
||||||
{
|
{
|
||||||
var foundBeatmap = await beatmapLookupCache.GetBeatmapAsync(Item.BeatmapID).ConfigureAwait(false);
|
IBeatmapInfo foundBeatmap;
|
||||||
|
|
||||||
|
if (multiplayerClient != null)
|
||||||
|
// This call can eventually go away (and use the else case below).
|
||||||
|
// Currently required only due to the method being overridden to provide special behaviour in tests.
|
||||||
|
foundBeatmap = await multiplayerClient.GetAPIBeatmap(Item.BeatmapID).ConfigureAwait(false);
|
||||||
|
else
|
||||||
|
foundBeatmap = await beatmapLookupCache.GetBeatmapAsync(Item.BeatmapID).ConfigureAwait(false);
|
||||||
|
|
||||||
Schedule(() => Item.Beatmap.Value = foundBeatmap);
|
Schedule(() => Item.Beatmap.Value = foundBeatmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
|||||||
public abstract class RoomSubScreen : OnlinePlaySubScreen, IPreviewTrackOwner
|
public abstract class RoomSubScreen : OnlinePlaySubScreen, IPreviewTrackOwner
|
||||||
{
|
{
|
||||||
[Cached(typeof(IBindable<PlaylistItem>))]
|
[Cached(typeof(IBindable<PlaylistItem>))]
|
||||||
protected readonly Bindable<PlaylistItem> SelectedItem = new Bindable<PlaylistItem>();
|
public readonly Bindable<PlaylistItem> SelectedItem = new Bindable<PlaylistItem>();
|
||||||
|
|
||||||
public override bool? AllowTrackAdjustments => true;
|
public override bool? AllowTrackAdjustments => true;
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
|||||||
protected OnlinePlayScreen ParentScreen { get; private set; }
|
protected OnlinePlayScreen ParentScreen { get; private set; }
|
||||||
|
|
||||||
[Cached]
|
[Cached]
|
||||||
private OnlinePlayBeatmapAvailabilityTracker beatmapAvailabilityTracker { get; set; }
|
private readonly OnlinePlayBeatmapAvailabilityTracker beatmapAvailabilityTracker = new OnlinePlayBeatmapAvailabilityTracker();
|
||||||
|
|
||||||
protected IBindable<BeatmapAvailability> BeatmapAvailability => beatmapAvailabilityTracker.Availability;
|
protected IBindable<BeatmapAvailability> BeatmapAvailability => beatmapAvailabilityTracker.Availability;
|
||||||
|
|
||||||
@ -90,11 +90,6 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
|||||||
|
|
||||||
Padding = new MarginPadding { Top = Header.HEIGHT };
|
Padding = new MarginPadding { Top = Header.HEIGHT };
|
||||||
|
|
||||||
beatmapAvailabilityTracker = new OnlinePlayBeatmapAvailabilityTracker
|
|
||||||
{
|
|
||||||
SelectedItem = { BindTarget = SelectedItem }
|
|
||||||
};
|
|
||||||
|
|
||||||
RoomId.BindTo(room.RoomID);
|
RoomId.BindTo(room.RoomID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,10 +242,10 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
|||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
SelectedItem.BindValueChanged(_ => Scheduler.AddOnce(selectedItemChanged));
|
SelectedItem.BindValueChanged(_ => Scheduler.AddOnce(selectedItemChanged));
|
||||||
|
|
||||||
beatmapManager.ItemUpdated += beatmapUpdated;
|
|
||||||
|
|
||||||
UserMods.BindValueChanged(_ => Scheduler.AddOnce(UpdateMods));
|
UserMods.BindValueChanged(_ => Scheduler.AddOnce(UpdateMods));
|
||||||
|
|
||||||
|
beatmapAvailabilityTracker.SelectedItem.BindTo(SelectedItem);
|
||||||
|
beatmapAvailabilityTracker.Availability.BindValueChanged(_ => updateWorkingBeatmap());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
@ -374,8 +369,6 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void beatmapUpdated(BeatmapSetInfo set) => Schedule(updateWorkingBeatmap);
|
|
||||||
|
|
||||||
private void updateWorkingBeatmap()
|
private void updateWorkingBeatmap()
|
||||||
{
|
{
|
||||||
var beatmap = SelectedItem.Value?.Beatmap.Value;
|
var beatmap = SelectedItem.Value?.Beatmap.Value;
|
||||||
@ -443,14 +436,6 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
|||||||
/// <param name="room">The room to change the settings of.</param>
|
/// <param name="room">The room to change the settings of.</param>
|
||||||
protected abstract RoomSettingsOverlay CreateRoomSettingsOverlay(Room room);
|
protected abstract RoomSettingsOverlay CreateRoomSettingsOverlay(Room room);
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
|
||||||
{
|
|
||||||
base.Dispose(isDisposing);
|
|
||||||
|
|
||||||
if (beatmapManager != null)
|
|
||||||
beatmapManager.ItemUpdated -= beatmapUpdated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class UserModSelectButton : PurpleTriangleButton
|
public class UserModSelectButton : PurpleTriangleButton
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,13 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
|||||||
sampleUnready = audio.Samples.Get(@"Multiplayer/player-unready");
|
sampleUnready = audio.Samples.Get(@"Multiplayer/player-unready");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
SelectedItem.BindValueChanged(_ => updateState());
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnRoomUpdated()
|
protected override void OnRoomUpdated()
|
||||||
{
|
{
|
||||||
base.OnRoomUpdated();
|
base.OnRoomUpdated();
|
||||||
@ -104,7 +111,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
|||||||
|
|
||||||
bool enableButton =
|
bool enableButton =
|
||||||
Room?.State == MultiplayerRoomState.Open
|
Room?.State == MultiplayerRoomState.Open
|
||||||
&& Client.CurrentMatchPlayingItem.Value?.Expired == false
|
&& SelectedItem.Value?.ID == Room.Settings.PlaylistItemId
|
||||||
|
&& !Room.Playlist.Single(i => i.ID == Room.Settings.PlaylistItemId).Expired
|
||||||
&& !operationInProgress.Value;
|
&& !operationInProgress.Value;
|
||||||
|
|
||||||
// When the local user is the host and spectating the match, the "start match" state should be enabled if any users are ready.
|
// When the local user is the host and spectating the match, the "start match" state should be enabled if any users are ready.
|
||||||
|
@ -25,7 +25,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private MultiplayerClient client { get; set; }
|
private MultiplayerClient client { get; set; }
|
||||||
|
|
||||||
private readonly PlaylistItem itemToEdit;
|
private readonly long? itemToEdit;
|
||||||
|
|
||||||
private LoadingLayer loadingLayer;
|
private LoadingLayer loadingLayer;
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
/// <param name="itemToEdit">The item to be edited. May be null, in which case a new item will be added to the playlist.</param>
|
/// <param name="itemToEdit">The item to be edited. May be null, in which case a new item will be added to the playlist.</param>
|
||||||
/// <param name="beatmap">An optional initial beatmap selection to perform.</param>
|
/// <param name="beatmap">An optional initial beatmap selection to perform.</param>
|
||||||
/// <param name="ruleset">An optional initial ruleset selection to perform.</param>
|
/// <param name="ruleset">An optional initial ruleset selection to perform.</param>
|
||||||
public MultiplayerMatchSongSelect(Room room, PlaylistItem itemToEdit = null, WorkingBeatmap beatmap = null, RulesetInfo ruleset = null)
|
public MultiplayerMatchSongSelect(Room room, long? itemToEdit = null, WorkingBeatmap beatmap = null, RulesetInfo ruleset = null)
|
||||||
: base(room)
|
: base(room)
|
||||||
{
|
{
|
||||||
this.itemToEdit = itemToEdit;
|
this.itemToEdit = itemToEdit;
|
||||||
@ -67,7 +67,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
|
|
||||||
var multiplayerItem = new MultiplayerPlaylistItem
|
var multiplayerItem = new MultiplayerPlaylistItem
|
||||||
{
|
{
|
||||||
ID = itemToEdit?.ID ?? 0,
|
ID = itemToEdit ?? 0,
|
||||||
BeatmapID = item.BeatmapID,
|
BeatmapID = item.BeatmapID,
|
||||||
BeatmapChecksum = item.Beatmap.Value.MD5Hash,
|
BeatmapChecksum = item.Beatmap.Value.MD5Hash,
|
||||||
RulesetID = item.RulesetID,
|
RulesetID = item.RulesetID,
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -67,8 +68,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
SelectedItem.BindTo(client.CurrentMatchPlayingItem);
|
|
||||||
|
|
||||||
BeatmapAvailability.BindValueChanged(updateBeatmapAvailability, true);
|
BeatmapAvailability.BindValueChanged(updateBeatmapAvailability, true);
|
||||||
UserMods.BindValueChanged(onUserModsChanged);
|
UserMods.BindValueChanged(onUserModsChanged);
|
||||||
|
|
||||||
@ -147,7 +146,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
new MultiplayerPlaylist
|
new MultiplayerPlaylist
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
RequestEdit = OpenSongSelection
|
RequestEdit = item => OpenSongSelection(item.ID)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new[]
|
new[]
|
||||||
@ -224,7 +223,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
/// Opens the song selection screen to add or edit an item.
|
/// Opens the song selection screen to add or edit an item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="itemToEdit">An optional playlist item to edit. If null, a new item will be added instead.</param>
|
/// <param name="itemToEdit">An optional playlist item to edit. If null, a new item will be added instead.</param>
|
||||||
internal void OpenSongSelection([CanBeNull] PlaylistItem itemToEdit = null)
|
internal void OpenSongSelection(long? itemToEdit = null)
|
||||||
{
|
{
|
||||||
if (!this.IsCurrentScreen())
|
if (!this.IsCurrentScreen())
|
||||||
return;
|
return;
|
||||||
@ -327,10 +326,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
if (client.LocalUser?.State == MultiplayerUserState.Ready)
|
if (client.LocalUser?.State == MultiplayerUserState.Ready)
|
||||||
client.ChangeState(MultiplayerUserState.Idle);
|
client.ChangeState(MultiplayerUserState.Idle);
|
||||||
}
|
}
|
||||||
else
|
else if (client.LocalUser?.State == MultiplayerUserState.Spectating
|
||||||
|
&& (client.Room?.State == MultiplayerRoomState.WaitingForLoad || client.Room?.State == MultiplayerRoomState.Playing))
|
||||||
{
|
{
|
||||||
if (client.LocalUser?.State == MultiplayerUserState.Spectating && (client.Room?.State == MultiplayerRoomState.WaitingForLoad || client.Room?.State == MultiplayerRoomState.Playing))
|
onLoadRequested();
|
||||||
onLoadRequested();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,11 +388,50 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateCurrentItem();
|
||||||
|
|
||||||
addItemButton.Alpha = client.IsHost || Room.QueueMode.Value != QueueMode.HostOnly ? 1 : 0;
|
addItemButton.Alpha = client.IsHost || Room.QueueMode.Value != QueueMode.HostOnly ? 1 : 0;
|
||||||
|
|
||||||
Scheduler.AddOnce(UpdateMods);
|
Scheduler.AddOnce(UpdateMods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateCurrentItem()
|
||||||
|
{
|
||||||
|
Debug.Assert(client.Room != null);
|
||||||
|
|
||||||
|
var expectedSelectedItem = Room.Playlist.SingleOrDefault(i => i.ID == client.Room.Settings.PlaylistItemId);
|
||||||
|
|
||||||
|
if (expectedSelectedItem == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// There's no reason to renew the selected item if its content hasn't changed.
|
||||||
|
if (SelectedItem.Value?.Equals(expectedSelectedItem) == true && expectedSelectedItem.Beatmap.Value != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Clear the selected item while the lookup is performed, so components like the ready button can enter their disabled states.
|
||||||
|
SelectedItem.Value = null;
|
||||||
|
|
||||||
|
if (expectedSelectedItem.Beatmap.Value == null)
|
||||||
|
{
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
var beatmap = await client.GetAPIBeatmap(expectedSelectedItem.BeatmapID).ConfigureAwait(false);
|
||||||
|
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
expectedSelectedItem.Beatmap.Value = beatmap;
|
||||||
|
|
||||||
|
if (Room.Playlist.SingleOrDefault(i => i.ID == client.Room?.Settings.PlaylistItemId)?.Equals(expectedSelectedItem) == true)
|
||||||
|
applyCurrentItem();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
applyCurrentItem();
|
||||||
|
|
||||||
|
void applyCurrentItem() => SelectedItem.Value = expectedSelectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
private void handleRoomLost() => Schedule(() =>
|
private void handleRoomLost() => Schedule(() =>
|
||||||
{
|
{
|
||||||
if (this.IsCurrentScreen())
|
if (this.IsCurrentScreen())
|
||||||
@ -446,6 +484,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
if (!this.IsCurrentScreen())
|
if (!this.IsCurrentScreen())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (client.Room == null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!client.IsHost)
|
if (!client.IsHost)
|
||||||
{
|
{
|
||||||
// todo: should handle this when the request queue is implemented.
|
// todo: should handle this when the request queue is implemented.
|
||||||
@ -454,7 +495,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Push(new MultiplayerMatchSongSelect(Room, SelectedItem.Value, beatmap, ruleset));
|
this.Push(new MultiplayerMatchSongSelect(Room, client.Room.Settings.PlaylistItemId, beatmap, ruleset));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
|
@ -87,6 +87,13 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
|||||||
{
|
{
|
||||||
var allScores = new List<MultiplayerScore> { userScore };
|
var allScores = new List<MultiplayerScore> { userScore };
|
||||||
|
|
||||||
|
// Other scores could have arrived between score submission and entering the results screen. Ensure the local player score position is up to date.
|
||||||
|
if (Score != null)
|
||||||
|
{
|
||||||
|
Score.Position = userScore.Position;
|
||||||
|
ScorePanelList.GetPanelForScore(Score).ScorePosition.Value = userScore.Position;
|
||||||
|
}
|
||||||
|
|
||||||
if (userScore.ScoresAround?.Higher != null)
|
if (userScore.ScoresAround?.Higher != null)
|
||||||
{
|
{
|
||||||
allScores.AddRange(userScore.ScoresAround.Higher.Scores);
|
allScores.AddRange(userScore.ScoresAround.Higher.Scores);
|
||||||
@ -186,12 +193,12 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
|||||||
Schedule(() =>
|
Schedule(() =>
|
||||||
{
|
{
|
||||||
// Prefer selecting the local user's score, or otherwise default to the first visible score.
|
// Prefer selecting the local user's score, or otherwise default to the first visible score.
|
||||||
SelectedScore.Value = scoreInfos.FirstOrDefault(s => s.User.Id == api.LocalUser.Value.Id) ?? scoreInfos.FirstOrDefault();
|
SelectedScore.Value = scoreInfos.FirstOrDefault(s => s.User.OnlineID == api.LocalUser.Value.Id) ?? scoreInfos.FirstOrDefault();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke callback to add the scores. Exclude the user's current score which was added previously.
|
// Invoke callback to add the scores. Exclude the user's current score which was added previously.
|
||||||
callback.Invoke(scoreInfos.Where(s => s.OnlineScoreID != Score?.OnlineScoreID));
|
callback.Invoke(scoreInfos.Where(s => s.OnlineID != Score?.OnlineID));
|
||||||
|
|
||||||
hideLoadingSpinners(pivot);
|
hideLoadingSpinners(pivot);
|
||||||
}));
|
}));
|
||||||
|
@ -6,6 +6,7 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using ManagedBass.Fx;
|
using ManagedBass.Fx;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
@ -18,6 +19,7 @@ using osu.Framework.Utils;
|
|||||||
using osu.Game.Audio.Effects;
|
using osu.Game.Audio.Effects;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
@ -58,6 +60,12 @@ namespace osu.Game.Screens.Play
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The player screen background, used to adjust appearance on failing.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public BackgroundScreen Background { private get; set; }
|
||||||
|
|
||||||
public FailAnimation(DrawableRuleset drawableRuleset)
|
public FailAnimation(DrawableRuleset drawableRuleset)
|
||||||
{
|
{
|
||||||
this.drawableRuleset = drawableRuleset;
|
this.drawableRuleset = drawableRuleset;
|
||||||
@ -136,6 +144,9 @@ namespace osu.Game.Screens.Play
|
|||||||
Content.ScaleTo(0.85f, duration, Easing.OutQuart);
|
Content.ScaleTo(0.85f, duration, Easing.OutQuart);
|
||||||
Content.RotateTo(1, duration, Easing.OutQuart);
|
Content.RotateTo(1, duration, Easing.OutQuart);
|
||||||
Content.FadeColour(Color4.Gray, duration);
|
Content.FadeColour(Color4.Gray, duration);
|
||||||
|
|
||||||
|
// Will be restored by `ApplyToBackground` logic in `SongSelect`.
|
||||||
|
Background?.FadeColour(OsuColour.Gray(0.3f), 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveFilters(bool resetTrackFrequency = true)
|
public void RemoveFilters(bool resetTrackFrequency = true)
|
||||||
|
@ -921,6 +921,8 @@ namespace osu.Game.Screens.Play
|
|||||||
b.IsBreakTime.BindTo(breakTracker.IsBreakTime);
|
b.IsBreakTime.BindTo(breakTracker.IsBreakTime);
|
||||||
|
|
||||||
b.StoryboardReplacesBackground.BindTo(storyboardReplacesBackground);
|
b.StoryboardReplacesBackground.BindTo(storyboardReplacesBackground);
|
||||||
|
|
||||||
|
failAnimationLayer.Background = b;
|
||||||
});
|
});
|
||||||
|
|
||||||
HUDOverlay.IsBreakTime.BindTo(breakTracker.IsBreakTime);
|
HUDOverlay.IsBreakTime.BindTo(breakTracker.IsBreakTime);
|
||||||
@ -1031,13 +1033,13 @@ namespace osu.Game.Screens.Play
|
|||||||
//
|
//
|
||||||
// Until we better define the server-side logic behind this, let's not store the online ID to avoid potential unique constraint
|
// Until we better define the server-side logic behind this, let's not store the online ID to avoid potential unique constraint
|
||||||
// conflicts across various systems (ie. solo and multiplayer).
|
// conflicts across various systems (ie. solo and multiplayer).
|
||||||
long? onlineScoreId = score.ScoreInfo.OnlineScoreID;
|
long? onlineScoreId = score.ScoreInfo.OnlineID;
|
||||||
score.ScoreInfo.OnlineScoreID = null;
|
score.ScoreInfo.OnlineID = -1;
|
||||||
|
|
||||||
await scoreManager.Import(score.ScoreInfo, replayReader).ConfigureAwait(false);
|
await scoreManager.Import(score.ScoreInfo, replayReader).ConfigureAwait(false);
|
||||||
|
|
||||||
// ... And restore the online ID for other processes to handle correctly (e.g. de-duplication for the results screen).
|
// ... And restore the online ID for other processes to handle correctly (e.g. de-duplication for the results screen).
|
||||||
score.ScoreInfo.OnlineScoreID = onlineScoreId;
|
score.ScoreInfo.OnlineID = onlineScoreId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -54,7 +54,7 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
private void userSentFrames(int userId, FrameDataBundle bundle)
|
private void userSentFrames(int userId, FrameDataBundle bundle)
|
||||||
{
|
{
|
||||||
if (userId != score.ScoreInfo.User.Id)
|
if (userId != score.ScoreInfo.User.OnlineID)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!LoadedBeatmapSuccessfully)
|
if (!LoadedBeatmapSuccessfully)
|
||||||
|
@ -156,7 +156,7 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
request.Success += s =>
|
request.Success += s =>
|
||||||
{
|
{
|
||||||
score.ScoreInfo.OnlineScoreID = s.ID;
|
score.ScoreInfo.OnlineID = s.ID;
|
||||||
score.ScoreInfo.Position = s.Position;
|
score.ScoreInfo.Position = s.Position;
|
||||||
|
|
||||||
scoreSubmissionSource.SetResult(true);
|
scoreSubmissionSource.SetResult(true);
|
||||||
|
@ -2,36 +2,42 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Scoring;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Ranking.Contracted
|
namespace osu.Game.Screens.Ranking.Contracted
|
||||||
{
|
{
|
||||||
public class ContractedPanelTopContent : CompositeDrawable
|
public class ContractedPanelTopContent : CompositeDrawable
|
||||||
{
|
{
|
||||||
private readonly ScoreInfo score;
|
public readonly Bindable<int?> ScorePosition = new Bindable<int?>();
|
||||||
|
|
||||||
public ContractedPanelTopContent(ScoreInfo score)
|
private OsuSpriteText text;
|
||||||
|
|
||||||
|
public ContractedPanelTopContent()
|
||||||
{
|
{
|
||||||
this.score = score;
|
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
InternalChild = new OsuSpriteText
|
InternalChild = text = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
Y = 6,
|
Y = 6,
|
||||||
Text = score.Position != null ? $"#{score.Position}" : string.Empty,
|
|
||||||
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold)
|
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
ScorePosition.BindValueChanged(pos => text.Text = pos.NewValue != null ? $"#{pos.NewValue}" : string.Empty, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using osu.Framework;
|
using osu.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
@ -78,6 +79,11 @@ namespace osu.Game.Screens.Ranking
|
|||||||
|
|
||||||
public event Action<PanelState> StateChanged;
|
public event Action<PanelState> StateChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The position of the score in the rankings.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Bindable<int?> ScorePosition = new Bindable<int?>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An action to be invoked if this <see cref="ScorePanel"/> is clicked while in an expanded state.
|
/// An action to be invoked if this <see cref="ScorePanel"/> is clicked while in an expanded state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -103,6 +109,8 @@ namespace osu.Game.Screens.Ranking
|
|||||||
{
|
{
|
||||||
Score = score;
|
Score = score;
|
||||||
displayWithFlair = isNewLocalScore;
|
displayWithFlair = isNewLocalScore;
|
||||||
|
|
||||||
|
ScorePosition.Value = score.Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -211,8 +219,8 @@ namespace osu.Game.Screens.Ranking
|
|||||||
topLayerBackground.FadeColour(expanded_top_layer_colour, RESIZE_DURATION, Easing.OutQuint);
|
topLayerBackground.FadeColour(expanded_top_layer_colour, RESIZE_DURATION, Easing.OutQuint);
|
||||||
middleLayerBackground.FadeColour(expanded_middle_layer_colour, RESIZE_DURATION, Easing.OutQuint);
|
middleLayerBackground.FadeColour(expanded_middle_layer_colour, RESIZE_DURATION, Easing.OutQuint);
|
||||||
|
|
||||||
topLayerContentContainer.Add(topLayerContent = new ExpandedPanelTopContent(Score.User).With(d => d.Alpha = 0));
|
topLayerContentContainer.Add(topLayerContent = new ExpandedPanelTopContent(Score.User) { Alpha = 0 });
|
||||||
middleLayerContentContainer.Add(middleLayerContent = new ExpandedPanelMiddleContent(Score, displayWithFlair).With(d => d.Alpha = 0));
|
middleLayerContentContainer.Add(middleLayerContent = new ExpandedPanelMiddleContent(Score, displayWithFlair) { Alpha = 0 });
|
||||||
|
|
||||||
// only the first expanded display should happen with flair.
|
// only the first expanded display should happen with flair.
|
||||||
displayWithFlair = false;
|
displayWithFlair = false;
|
||||||
@ -224,8 +232,13 @@ namespace osu.Game.Screens.Ranking
|
|||||||
topLayerBackground.FadeColour(contracted_top_layer_colour, RESIZE_DURATION, Easing.OutQuint);
|
topLayerBackground.FadeColour(contracted_top_layer_colour, RESIZE_DURATION, Easing.OutQuint);
|
||||||
middleLayerBackground.FadeColour(contracted_middle_layer_colour, RESIZE_DURATION, Easing.OutQuint);
|
middleLayerBackground.FadeColour(contracted_middle_layer_colour, RESIZE_DURATION, Easing.OutQuint);
|
||||||
|
|
||||||
topLayerContentContainer.Add(topLayerContent = new ContractedPanelTopContent(Score).With(d => d.Alpha = 0));
|
topLayerContentContainer.Add(topLayerContent = new ContractedPanelTopContent
|
||||||
middleLayerContentContainer.Add(middleLayerContent = new ContractedPanelMiddleContent(Score).With(d => d.Alpha = 0));
|
{
|
||||||
|
ScorePosition = { BindTarget = ScorePosition },
|
||||||
|
Alpha = 0
|
||||||
|
});
|
||||||
|
|
||||||
|
middleLayerContentContainer.Add(middleLayerContent = new ContractedPanelMiddleContent(Score) { Alpha = 0 });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ namespace osu.Game.Screens.Ranking
|
|||||||
|
|
||||||
private IEnumerable<ScorePanelTrackingContainer> applySorting(IEnumerable<Drawable> drawables) => drawables.OfType<ScorePanelTrackingContainer>()
|
private IEnumerable<ScorePanelTrackingContainer> applySorting(IEnumerable<Drawable> drawables) => drawables.OfType<ScorePanelTrackingContainer>()
|
||||||
.OrderByDescending(GetLayoutPosition)
|
.OrderByDescending(GetLayoutPosition)
|
||||||
.ThenBy(s => s.Panel.Score.OnlineScoreID);
|
.ThenBy(s => s.Panel.Score.OnlineID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Scroll : OsuScrollContainer
|
private class Scroll : OsuScrollContainer
|
||||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Screens.Ranking
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
getScoreRequest = new GetScoresRequest(Score.BeatmapInfo, Score.Ruleset);
|
getScoreRequest = new GetScoresRequest(Score.BeatmapInfo, Score.Ruleset);
|
||||||
getScoreRequest.Success += r => scoresCallback?.Invoke(r.Scores.Where(s => s.OnlineID != Score.OnlineScoreID).Select(s => s.CreateScoreInfo(rulesets, Beatmap.Value.BeatmapInfo)));
|
getScoreRequest.Success += r => scoresCallback?.Invoke(r.Scores.Where(s => s.OnlineID != Score.OnlineID).Select(s => s.CreateScoreInfo(rulesets, Beatmap.Value.BeatmapInfo)));
|
||||||
return getScoreRequest;
|
return getScoreRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,10 +33,8 @@ namespace osu.Game.Storyboards
|
|||||||
|
|
||||||
foreach (var l in loops)
|
foreach (var l in loops)
|
||||||
{
|
{
|
||||||
if (!(l.EarliestDisplayedTime is double lEarliest))
|
if (l.EarliestDisplayedTime is double loopEarliestDisplayTime)
|
||||||
continue;
|
earliestStartTime = Math.Min(earliestStartTime, l.LoopStartTime + loopEarliestDisplayTime);
|
||||||
|
|
||||||
earliestStartTime = Math.Min(earliestStartTime, lEarliest);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (earliestStartTime < double.MaxValue)
|
if (earliestStartTime < double.MaxValue)
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osu.Game.Scoring;
|
|
||||||
using osu.Game.Tests.Beatmaps;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests
|
|
||||||
{
|
|
||||||
public class TestScoreInfo : ScoreInfo
|
|
||||||
{
|
|
||||||
public TestScoreInfo(RulesetInfo ruleset, bool excessMods = false)
|
|
||||||
{
|
|
||||||
User = new APIUser
|
|
||||||
{
|
|
||||||
Id = 2,
|
|
||||||
Username = "peppy",
|
|
||||||
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
|
|
||||||
};
|
|
||||||
|
|
||||||
BeatmapInfo = new TestBeatmap(ruleset).BeatmapInfo;
|
|
||||||
Ruleset = ruleset;
|
|
||||||
RulesetID = ruleset.ID ?? 0;
|
|
||||||
|
|
||||||
Mods = excessMods
|
|
||||||
? ruleset.CreateInstance().CreateAllMods().ToArray()
|
|
||||||
: new Mod[] { new TestModHardRock(), new TestModDoubleTime() };
|
|
||||||
|
|
||||||
TotalScore = 2845370;
|
|
||||||
Accuracy = 0.95;
|
|
||||||
MaxCombo = 999;
|
|
||||||
Rank = ScoreRank.S;
|
|
||||||
Date = DateTimeOffset.Now;
|
|
||||||
|
|
||||||
Statistics[HitResult.Miss] = 1;
|
|
||||||
Statistics[HitResult.Meh] = 50;
|
|
||||||
Statistics[HitResult.Ok] = 100;
|
|
||||||
Statistics[HitResult.Good] = 200;
|
|
||||||
Statistics[HitResult.Great] = 300;
|
|
||||||
Statistics[HitResult.Perfect] = 320;
|
|
||||||
Statistics[HitResult.SmallTickHit] = 50;
|
|
||||||
Statistics[HitResult.SmallTickMiss] = 25;
|
|
||||||
Statistics[HitResult.LargeTickHit] = 100;
|
|
||||||
Statistics[HitResult.LargeTickMiss] = 50;
|
|
||||||
Statistics[HitResult.SmallBonus] = 10;
|
|
||||||
Statistics[HitResult.SmallBonus] = 50;
|
|
||||||
|
|
||||||
Position = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestModHardRock : ModHardRock
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestModDoubleTime : ModDoubleTime
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -376,7 +376,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
public override Task RemovePlaylistItem(long playlistItemId) => RemoveUserPlaylistItem(api.LocalUser.Value.OnlineID, playlistItemId);
|
public override Task RemovePlaylistItem(long playlistItemId) => RemoveUserPlaylistItem(api.LocalUser.Value.OnlineID, playlistItemId);
|
||||||
|
|
||||||
protected override Task<APIBeatmap> GetAPIBeatmap(int beatmapId, CancellationToken cancellationToken = default)
|
public override Task<APIBeatmap> GetAPIBeatmap(int beatmapId, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
IBeatmapSetInfo? set = roomManager.ServerSideRooms.SelectMany(r => r.Playlist)
|
IBeatmapSetInfo? set = roomManager.ServerSideRooms.SelectMany(r => r.Playlist)
|
||||||
.FirstOrDefault(p => p.BeatmapID == beatmapId)?.Beatmap.Value.BeatmapSet
|
.FirstOrDefault(p => p.BeatmapID == beatmapId)?.Beatmap.Value.BeatmapSet
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="AutoMapper" Version="10.1.1" />
|
<PackageReference Include="AutoMapper" Version="10.1.1" />
|
||||||
<PackageReference Include="DiffPlex" Version="1.7.0" />
|
<PackageReference Include="DiffPlex" Version="1.7.0" />
|
||||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.38" />
|
<PackageReference Include="HtmlAgilityPack" Version="1.11.39" />
|
||||||
<PackageReference Include="Humanizer" Version="2.13.14" />
|
<PackageReference Include="Humanizer" Version="2.13.14" />
|
||||||
<PackageReference Include="MessagePack" Version="2.3.85" />
|
<PackageReference Include="MessagePack" Version="2.3.85" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.11" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.11" />
|
||||||
@ -31,15 +31,15 @@
|
|||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" />
|
<PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="ppy.LocalisationAnalyser" Version="2021.725.0">
|
<PackageReference Include="ppy.LocalisationAnalyser" Version="2021.1210.0">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Realm" Version="10.7.1" />
|
<PackageReference Include="Realm" Version="10.7.1" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2021.1207.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2021.1210.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1203.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1203.0" />
|
||||||
<PackageReference Include="Sentry" Version="3.11.1" />
|
<PackageReference Include="Sentry" Version="3.12.1" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.30.0" />
|
<PackageReference Include="SharpCompress" Version="0.30.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
<PackageReference Include="TagLibSharp" Version="2.2.0" />
|
<PackageReference Include="TagLibSharp" Version="2.2.0" />
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.1207.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.1210.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1203.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1203.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
||||||
@ -83,7 +83,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2021.1207.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2021.1210.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.30.0" />
|
<PackageReference Include="SharpCompress" Version="0.30.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user