mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 20:22:55 +08:00
Merge branch 'master' into enhance-mod-settings-text-box-visibility
This commit is contained in:
commit
e9d4ee3c87
@ -17,7 +17,11 @@ build:
|
|||||||
publish_nuget: true
|
publish_nuget: true
|
||||||
after_build:
|
after_build:
|
||||||
- ps: dotnet tool restore
|
- ps: dotnet tool restore
|
||||||
- ps: dotnet format --dry-run --check
|
|
||||||
|
# Temporarily disabled until the tool is upgraded to 5.0.
|
||||||
|
# The version specified in .config/dotnet-tools.json (3.1.37601) won't run on .NET hosts >=5.0.7.
|
||||||
|
# - ps: dotnet format --dry-run --check
|
||||||
|
|
||||||
- ps: .\InspectCode.ps1
|
- ps: .\InspectCode.ps1
|
||||||
test:
|
test:
|
||||||
assemblies:
|
assemblies:
|
||||||
|
@ -52,6 +52,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.611.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.611.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.611.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.614.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -2,15 +2,22 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Online.Leaderboards;
|
using osu.Game.Online.Leaderboards;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
using osu.Game.Screens.Select.Leaderboards;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -23,32 +30,98 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
[Cached]
|
[Cached]
|
||||||
private readonly DialogOverlay dialogOverlay;
|
private readonly DialogOverlay dialogOverlay;
|
||||||
|
|
||||||
|
private ScoreManager scoreManager;
|
||||||
|
|
||||||
|
private RulesetStore rulesetStore;
|
||||||
|
private BeatmapManager beatmapManager;
|
||||||
|
|
||||||
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
|
{
|
||||||
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
|
dependencies.Cache(rulesetStore = new RulesetStore(ContextFactory));
|
||||||
|
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
|
||||||
|
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, null, ContextFactory));
|
||||||
|
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
public TestSceneBeatmapLeaderboard()
|
public TestSceneBeatmapLeaderboard()
|
||||||
{
|
{
|
||||||
Add(dialogOverlay = new DialogOverlay
|
AddRange(new Drawable[]
|
||||||
{
|
{
|
||||||
Depth = -1
|
dialogOverlay = new DialogOverlay
|
||||||
|
{
|
||||||
|
Depth = -1
|
||||||
|
},
|
||||||
|
leaderboard = new FailableLeaderboard
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Size = new Vector2(550f, 450f),
|
||||||
|
Scope = BeatmapLeaderboardScope.Global,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLocalScoresDisplay()
|
||||||
|
{
|
||||||
|
BeatmapInfo beatmapInfo = null;
|
||||||
|
|
||||||
|
AddStep(@"Set scope", () => leaderboard.Scope = BeatmapLeaderboardScope.Local);
|
||||||
|
|
||||||
|
AddStep(@"Set beatmap", () =>
|
||||||
|
{
|
||||||
|
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
|
||||||
|
beatmapInfo = beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps.First();
|
||||||
|
|
||||||
|
leaderboard.Beatmap = beatmapInfo;
|
||||||
});
|
});
|
||||||
|
|
||||||
Add(leaderboard = new FailableLeaderboard
|
clearScores();
|
||||||
{
|
checkCount(0);
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Size = new Vector2(550f, 450f),
|
|
||||||
Scope = BeatmapLeaderboardScope.Global,
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep(@"New Scores", newScores);
|
loadMoreScores(() => beatmapInfo);
|
||||||
|
checkCount(10);
|
||||||
|
|
||||||
|
loadMoreScores(() => beatmapInfo);
|
||||||
|
checkCount(20);
|
||||||
|
|
||||||
|
clearScores();
|
||||||
|
checkCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestGlobalScoresDisplay()
|
||||||
|
{
|
||||||
|
AddStep(@"Set scope", () => leaderboard.Scope = BeatmapLeaderboardScope.Global);
|
||||||
|
AddStep(@"New Scores", () => leaderboard.Scores = generateSampleScores(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestPersonalBest()
|
||||||
|
{
|
||||||
AddStep(@"Show personal best", showPersonalBest);
|
AddStep(@"Show personal best", showPersonalBest);
|
||||||
|
AddStep("null personal best position", showPersonalBestWithNullPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestPlaceholderStates()
|
||||||
|
{
|
||||||
AddStep(@"Empty Scores", () => leaderboard.SetRetrievalState(PlaceholderState.NoScores));
|
AddStep(@"Empty Scores", () => leaderboard.SetRetrievalState(PlaceholderState.NoScores));
|
||||||
AddStep(@"Network failure", () => leaderboard.SetRetrievalState(PlaceholderState.NetworkFailure));
|
AddStep(@"Network failure", () => leaderboard.SetRetrievalState(PlaceholderState.NetworkFailure));
|
||||||
AddStep(@"No supporter", () => leaderboard.SetRetrievalState(PlaceholderState.NotSupporter));
|
AddStep(@"No supporter", () => leaderboard.SetRetrievalState(PlaceholderState.NotSupporter));
|
||||||
AddStep(@"Not logged in", () => leaderboard.SetRetrievalState(PlaceholderState.NotLoggedIn));
|
AddStep(@"Not logged in", () => leaderboard.SetRetrievalState(PlaceholderState.NotLoggedIn));
|
||||||
AddStep(@"Unavailable", () => leaderboard.SetRetrievalState(PlaceholderState.Unavailable));
|
AddStep(@"Unavailable", () => leaderboard.SetRetrievalState(PlaceholderState.Unavailable));
|
||||||
AddStep(@"None selected", () => leaderboard.SetRetrievalState(PlaceholderState.NoneSelected));
|
AddStep(@"None selected", () => leaderboard.SetRetrievalState(PlaceholderState.NoneSelected));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestBeatmapStates()
|
||||||
|
{
|
||||||
foreach (BeatmapSetOnlineStatus status in Enum.GetValues(typeof(BeatmapSetOnlineStatus)))
|
foreach (BeatmapSetOnlineStatus status in Enum.GetValues(typeof(BeatmapSetOnlineStatus)))
|
||||||
AddStep($"{status} beatmap", () => showBeatmapWithStatus(status));
|
AddStep($"{status} beatmap", () => showBeatmapWithStatus(status));
|
||||||
AddStep("null personal best position", showPersonalBestWithNullPosition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showPersonalBestWithNullPosition()
|
private void showPersonalBestWithNullPosition()
|
||||||
@ -96,9 +169,26 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void newScores()
|
private void loadMoreScores(Func<BeatmapInfo> beatmapInfo)
|
||||||
{
|
{
|
||||||
var scores = new[]
|
AddStep(@"Load new scores via manager", () =>
|
||||||
|
{
|
||||||
|
foreach (var score in generateSampleScores(beatmapInfo()))
|
||||||
|
scoreManager.Import(score).Wait();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearScores()
|
||||||
|
{
|
||||||
|
AddStep("Clear all scores", () => scoreManager.Delete(scoreManager.GetAllUsableScores()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCount(int expected) =>
|
||||||
|
AddUntilStep("Correct count displayed", () => leaderboard.ChildrenOfType<LeaderboardScore>().Count() == expected);
|
||||||
|
|
||||||
|
private static ScoreInfo[] generateSampleScores(BeatmapInfo beatmap)
|
||||||
|
{
|
||||||
|
return new[]
|
||||||
{
|
{
|
||||||
new ScoreInfo
|
new ScoreInfo
|
||||||
{
|
{
|
||||||
@ -107,6 +197,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
||||||
|
Beatmap = beatmap,
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
Id = 6602580,
|
Id = 6602580,
|
||||||
@ -125,6 +216,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
||||||
|
Beatmap = beatmap,
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
Id = 4608074,
|
Id = 4608074,
|
||||||
@ -143,6 +235,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
||||||
|
Beatmap = beatmap,
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
Id = 1014222,
|
Id = 1014222,
|
||||||
@ -161,6 +254,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
||||||
|
Beatmap = beatmap,
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
Id = 1541390,
|
Id = 1541390,
|
||||||
@ -179,6 +273,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
||||||
|
Beatmap = beatmap,
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
Id = 2243452,
|
Id = 2243452,
|
||||||
@ -197,6 +292,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
||||||
|
Beatmap = beatmap,
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
Id = 2705430,
|
Id = 2705430,
|
||||||
@ -215,6 +311,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
||||||
|
Beatmap = beatmap,
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
Id = 7151382,
|
Id = 7151382,
|
||||||
@ -233,6 +330,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
||||||
|
Beatmap = beatmap,
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
Id = 2051389,
|
Id = 2051389,
|
||||||
@ -251,6 +349,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
||||||
|
Beatmap = beatmap,
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
Id = 6169483,
|
Id = 6169483,
|
||||||
@ -269,6 +368,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
//Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
|
||||||
|
Beatmap = beatmap,
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
Id = 6702666,
|
Id = 6702666,
|
||||||
@ -281,8 +381,6 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
leaderboard.Scores = scores;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showBeatmapWithStatus(BeatmapSetOnlineStatus status)
|
private void showBeatmapWithStatus(BeatmapSetOnlineStatus status)
|
||||||
|
@ -1,20 +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.ComponentModel;
|
|
||||||
|
|
||||||
namespace osu.Game.Configuration
|
|
||||||
{
|
|
||||||
public enum RankingType
|
|
||||||
{
|
|
||||||
Local,
|
|
||||||
|
|
||||||
[Description("Global")]
|
|
||||||
Top,
|
|
||||||
|
|
||||||
[Description("Selected Mods")]
|
|
||||||
SelectedMod,
|
|
||||||
Friends,
|
|
||||||
Country
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,17 +7,17 @@ namespace osu.Game.Localisation
|
|||||||
{
|
{
|
||||||
public static class ChatStrings
|
public static class ChatStrings
|
||||||
{
|
{
|
||||||
private const string prefix = "osu.Game.Localisation.Chat";
|
private const string prefix = @"osu.Game.Localisation.Chat";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "chat"
|
/// "chat"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString HeaderTitle => new TranslatableString(getKey("header_title"), "chat");
|
public static LocalisableString HeaderTitle => new TranslatableString(getKey(@"header_title"), @"chat");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "join the real-time discussion"
|
/// "join the real-time discussion"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString HeaderDescription => new TranslatableString(getKey("header_description"), "join the real-time discussion");
|
public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"join the real-time discussion");
|
||||||
|
|
||||||
private static string getKey(string key) => $"{prefix}:{key}";
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,12 @@ namespace osu.Game.Localisation
|
|||||||
{
|
{
|
||||||
public static class CommonStrings
|
public static class CommonStrings
|
||||||
{
|
{
|
||||||
private const string prefix = "osu.Game.Localisation.Common";
|
private const string prefix = @"osu.Game.Localisation.Common";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Cancel"
|
/// "Cancel"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString Cancel => new TranslatableString(getKey("cancel"), "Cancel");
|
public static LocalisableString Cancel => new TranslatableString(getKey(@"cancel"), @"Cancel");
|
||||||
|
|
||||||
private static string getKey(string key) => $"{prefix}:{key}";
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ namespace osu.Game.Localisation
|
|||||||
{
|
{
|
||||||
public enum Language
|
public enum Language
|
||||||
{
|
{
|
||||||
[Description("English")]
|
[Description(@"English")]
|
||||||
en,
|
en,
|
||||||
|
|
||||||
[Description("日本語")]
|
[Description(@"日本語")]
|
||||||
ja
|
ja
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,17 @@ namespace osu.Game.Localisation
|
|||||||
{
|
{
|
||||||
public static class NotificationsStrings
|
public static class NotificationsStrings
|
||||||
{
|
{
|
||||||
private const string prefix = "osu.Game.Localisation.Notifications";
|
private const string prefix = @"osu.Game.Localisation.Notifications";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "notifications"
|
/// "notifications"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString HeaderTitle => new TranslatableString(getKey("header_title"), "notifications");
|
public static LocalisableString HeaderTitle => new TranslatableString(getKey(@"header_title"), @"notifications");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "waiting for 'ya"
|
/// "waiting for 'ya"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString HeaderDescription => new TranslatableString(getKey("header_description"), "waiting for 'ya");
|
public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"waiting for 'ya");
|
||||||
|
|
||||||
private static string getKey(string key) => $"{prefix}:{key}";
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,17 @@ namespace osu.Game.Localisation
|
|||||||
{
|
{
|
||||||
public static class NowPlayingStrings
|
public static class NowPlayingStrings
|
||||||
{
|
{
|
||||||
private const string prefix = "osu.Game.Localisation.NowPlaying";
|
private const string prefix = @"osu.Game.Localisation.NowPlaying";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "now playing"
|
/// "now playing"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString HeaderTitle => new TranslatableString(getKey("header_title"), "now playing");
|
public static LocalisableString HeaderTitle => new TranslatableString(getKey(@"header_title"), @"now playing");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "manage the currently playing track"
|
/// "manage the currently playing track"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString HeaderDescription => new TranslatableString(getKey("header_description"), "manage the currently playing track");
|
public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"manage the currently playing track");
|
||||||
|
|
||||||
private static string getKey(string key) => $"{prefix}:{key}";
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Resources;
|
using System.Resources;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
@ -34,7 +35,29 @@ namespace osu.Game.Localisation
|
|||||||
lock (resourceManagers)
|
lock (resourceManagers)
|
||||||
{
|
{
|
||||||
if (!resourceManagers.TryGetValue(ns, out var manager))
|
if (!resourceManagers.TryGetValue(ns, out var manager))
|
||||||
resourceManagers[ns] = manager = new ResourceManager(ns, GetType().Assembly);
|
{
|
||||||
|
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||||
|
|
||||||
|
// Traverse backwards through periods in the namespace to find a matching assembly.
|
||||||
|
string assemblyName = ns;
|
||||||
|
|
||||||
|
while (!string.IsNullOrEmpty(assemblyName))
|
||||||
|
{
|
||||||
|
var matchingAssembly = loadedAssemblies.FirstOrDefault(asm => asm.GetName().Name == assemblyName);
|
||||||
|
|
||||||
|
if (matchingAssembly != null)
|
||||||
|
{
|
||||||
|
resourceManagers[ns] = manager = new ResourceManager(ns, matchingAssembly);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lastIndex = Math.Max(0, assemblyName.LastIndexOf('.'));
|
||||||
|
assemblyName = assemblyName.Substring(0, lastIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manager == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -7,17 +7,17 @@ namespace osu.Game.Localisation
|
|||||||
{
|
{
|
||||||
public static class SettingsStrings
|
public static class SettingsStrings
|
||||||
{
|
{
|
||||||
private const string prefix = "osu.Game.Localisation.Settings";
|
private const string prefix = @"osu.Game.Localisation.Settings";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "settings"
|
/// "settings"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString HeaderTitle => new TranslatableString(getKey("header_title"), "settings");
|
public static LocalisableString HeaderTitle => new TranslatableString(getKey(@"header_title"), @"settings");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "change the way osu! behaves"
|
/// "change the way osu! behaves"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString HeaderDescription => new TranslatableString(getKey("header_description"), "change the way osu! behaves");
|
public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"change the way osu! behaves");
|
||||||
|
|
||||||
private static string getKey(string key) => $"{prefix}:{key}";
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,9 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
|
|
||||||
protected override Container<Drawable> Content => content;
|
protected override Container<Drawable> Content => content;
|
||||||
|
|
||||||
private IEnumerable<TScoreInfo> scores;
|
private ICollection<TScoreInfo> scores;
|
||||||
|
|
||||||
public IEnumerable<TScoreInfo> Scores
|
public ICollection<TScoreInfo> Scores
|
||||||
{
|
{
|
||||||
get => scores;
|
get => scores;
|
||||||
set
|
set
|
||||||
@ -126,7 +126,7 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
scope = value;
|
scope = value;
|
||||||
UpdateScores();
|
RefreshScores();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
case PlaceholderState.NetworkFailure:
|
case PlaceholderState.NetworkFailure:
|
||||||
replacePlaceholder(new ClickablePlaceholder(@"Couldn't fetch scores!", FontAwesome.Solid.Sync)
|
replacePlaceholder(new ClickablePlaceholder(@"Couldn't fetch scores!", FontAwesome.Solid.Sync)
|
||||||
{
|
{
|
||||||
Action = UpdateScores,
|
Action = RefreshScores
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -254,8 +254,6 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
apiState.BindValueChanged(onlineStateChanged, true);
|
apiState.BindValueChanged(onlineStateChanged, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshScores() => UpdateScores();
|
|
||||||
|
|
||||||
private APIRequest getScoresRequest;
|
private APIRequest getScoresRequest;
|
||||||
|
|
||||||
protected abstract bool IsOnlineScope { get; }
|
protected abstract bool IsOnlineScope { get; }
|
||||||
@ -267,12 +265,14 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
case APIState.Online:
|
case APIState.Online:
|
||||||
case APIState.Offline:
|
case APIState.Offline:
|
||||||
if (IsOnlineScope)
|
if (IsOnlineScope)
|
||||||
UpdateScores();
|
RefreshScores();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
public void RefreshScores() => Scheduler.AddOnce(UpdateScores);
|
||||||
|
|
||||||
protected void UpdateScores()
|
protected void UpdateScores()
|
||||||
{
|
{
|
||||||
// don't display any scores or placeholder until the first Scores_Set has been called.
|
// don't display any scores or placeholder until the first Scores_Set has been called.
|
||||||
@ -290,7 +290,7 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
|
|
||||||
getScoresRequest = FetchScores(scores => Schedule(() =>
|
getScoresRequest = FetchScores(scores => Schedule(() =>
|
||||||
{
|
{
|
||||||
Scores = scores;
|
Scores = scores.ToArray();
|
||||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -19,6 +19,20 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
private readonly IBindable<double> timeRange = new BindableDouble();
|
private readonly IBindable<double> timeRange = new BindableDouble();
|
||||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the scrolling direction is horizontal or vertical.
|
||||||
|
/// </summary>
|
||||||
|
private Direction scrollingAxis => direction.Value == ScrollingDirection.Left || direction.Value == ScrollingDirection.Right ? Direction.Horizontal : Direction.Vertical;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The scrolling axis is inverted if objects temporally farther in the future have a smaller position value across the scrolling axis.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <see cref="ScrollingDirection.Down"/> is inverted, because given two objects, one of which is at the current time and one of which is 1000ms in the future,
|
||||||
|
/// in the current time instant the future object is spatially above the current object, and therefore has a smaller value of the Y coordinate of its position.
|
||||||
|
/// </example>
|
||||||
|
private bool axisInverted => direction.Value == ScrollingDirection.Down || direction.Value == ScrollingDirection.Right;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A set of top-level <see cref="DrawableHitObject"/>s which have an up-to-date layout.
|
/// A set of top-level <see cref="DrawableHitObject"/>s which have an up-to-date layout.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -48,99 +62,64 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Given a position in screen space, return the time within this column.
|
/// Given a position at <paramref name="currentTime"/>, return the time of the object corresponding to the position.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double TimeAtScreenSpacePosition(Vector2 screenSpacePosition)
|
/// <remarks>
|
||||||
|
/// If there are multiple valid time values, one arbitrary time is returned.
|
||||||
|
/// </remarks>
|
||||||
|
public double TimeAtPosition(float localPosition, double currentTime)
|
||||||
{
|
{
|
||||||
// convert to local space of column so we can snap and fetch correct location.
|
float scrollPosition = axisInverted ? scrollLength - localPosition : localPosition;
|
||||||
Vector2 localPosition = ToLocalSpace(screenSpacePosition);
|
return scrollingInfo.Algorithm.TimeAt(scrollPosition, currentTime, timeRange.Value, scrollLength);
|
||||||
|
|
||||||
float position = 0;
|
|
||||||
|
|
||||||
switch (scrollingInfo.Direction.Value)
|
|
||||||
{
|
|
||||||
case ScrollingDirection.Up:
|
|
||||||
case ScrollingDirection.Down:
|
|
||||||
position = localPosition.Y;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ScrollingDirection.Right:
|
|
||||||
case ScrollingDirection.Left:
|
|
||||||
position = localPosition.X;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
flipPositionIfRequired(ref position);
|
|
||||||
|
|
||||||
return scrollingInfo.Algorithm.TimeAt(position, Time.Current, scrollingInfo.TimeRange.Value, scrollLength);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Given a time, return the screen space position within this column.
|
/// Given a position at the current time in screen space, return the time of the object corresponding the position.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If there are multiple valid time values, one arbitrary time is returned.
|
||||||
|
/// </remarks>
|
||||||
|
public double TimeAtScreenSpacePosition(Vector2 screenSpacePosition)
|
||||||
|
{
|
||||||
|
Vector2 localPosition = ToLocalSpace(screenSpacePosition);
|
||||||
|
return TimeAtPosition(scrollingAxis == Direction.Horizontal ? localPosition.X : localPosition.Y, Time.Current);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Given a time, return the position along the scrolling axis within this <see cref="HitObjectContainer"/> at time <paramref name="currentTime"/>.
|
||||||
|
/// </summary>
|
||||||
|
public float PositionAtTime(double time, double currentTime)
|
||||||
|
{
|
||||||
|
float scrollPosition = scrollingInfo.Algorithm.PositionAt(time, currentTime, timeRange.Value, scrollLength);
|
||||||
|
return axisInverted ? scrollLength - scrollPosition : scrollPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Given a time, return the position along the scrolling axis within this <see cref="HitObjectContainer"/> at the current time.
|
||||||
|
/// </summary>
|
||||||
|
public float PositionAtTime(double time) => PositionAtTime(time, Time.Current);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Given a time, return the screen space position within this <see cref="HitObjectContainer"/>.
|
||||||
|
/// In the non-scrolling axis, the center of this <see cref="HitObjectContainer"/> is returned.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector2 ScreenSpacePositionAtTime(double time)
|
public Vector2 ScreenSpacePositionAtTime(double time)
|
||||||
{
|
{
|
||||||
var pos = scrollingInfo.Algorithm.PositionAt(time, Time.Current, scrollingInfo.TimeRange.Value, scrollLength);
|
float localPosition = PositionAtTime(time, Time.Current);
|
||||||
|
return scrollingAxis == Direction.Horizontal
|
||||||
flipPositionIfRequired(ref pos);
|
? ToScreenSpace(new Vector2(localPosition, DrawHeight / 2))
|
||||||
|
: ToScreenSpace(new Vector2(DrawWidth / 2, localPosition));
|
||||||
switch (scrollingInfo.Direction.Value)
|
|
||||||
{
|
|
||||||
case ScrollingDirection.Up:
|
|
||||||
case ScrollingDirection.Down:
|
|
||||||
return ToScreenSpace(new Vector2(getBreadth() / 2, pos));
|
|
||||||
|
|
||||||
default:
|
|
||||||
return ToScreenSpace(new Vector2(pos, getBreadth() / 2));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private float scrollLength
|
/// <summary>
|
||||||
|
/// Given a start time and end time of a scrolling object, return the length of the object along the scrolling axis.
|
||||||
|
/// </summary>
|
||||||
|
public float LengthAtTime(double startTime, double endTime)
|
||||||
{
|
{
|
||||||
get
|
return scrollingInfo.Algorithm.GetLength(startTime, endTime, timeRange.Value, scrollLength);
|
||||||
{
|
|
||||||
switch (scrollingInfo.Direction.Value)
|
|
||||||
{
|
|
||||||
case ScrollingDirection.Left:
|
|
||||||
case ScrollingDirection.Right:
|
|
||||||
return DrawWidth;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return DrawHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private float getBreadth()
|
private float scrollLength => scrollingAxis == Direction.Horizontal ? DrawWidth : DrawHeight;
|
||||||
{
|
|
||||||
switch (scrollingInfo.Direction.Value)
|
|
||||||
{
|
|
||||||
case ScrollingDirection.Up:
|
|
||||||
case ScrollingDirection.Down:
|
|
||||||
return DrawWidth;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return DrawHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void flipPositionIfRequired(ref float position)
|
|
||||||
{
|
|
||||||
// We're dealing with screen coordinates in which the position decreases towards the centre of the screen resulting in an increase in start time.
|
|
||||||
// The scrolling algorithm instead assumes a top anchor meaning an increase in time corresponds to an increase in position,
|
|
||||||
// so when scrolling downwards the coordinates need to be flipped.
|
|
||||||
|
|
||||||
switch (scrollingInfo.Direction.Value)
|
|
||||||
{
|
|
||||||
case ScrollingDirection.Down:
|
|
||||||
position = DrawHeight - position;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ScrollingDirection.Right:
|
|
||||||
position = DrawWidth - position;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void AddDrawable(HitObjectLifetimeEntry entry, DrawableHitObject drawable)
|
protected override void AddDrawable(HitObjectLifetimeEntry entry, DrawableHitObject drawable)
|
||||||
{
|
{
|
||||||
@ -237,18 +216,11 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
{
|
{
|
||||||
if (hitObject.HitObject is IHasDuration e)
|
if (hitObject.HitObject is IHasDuration e)
|
||||||
{
|
{
|
||||||
switch (direction.Value)
|
float length = LengthAtTime(hitObject.HitObject.StartTime, e.EndTime);
|
||||||
{
|
if (scrollingAxis == Direction.Horizontal)
|
||||||
case ScrollingDirection.Up:
|
hitObject.Width = length;
|
||||||
case ScrollingDirection.Down:
|
else
|
||||||
hitObject.Height = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, e.EndTime, timeRange.Value, scrollLength);
|
hitObject.Height = length;
|
||||||
break;
|
|
||||||
|
|
||||||
case ScrollingDirection.Left:
|
|
||||||
case ScrollingDirection.Right:
|
|
||||||
hitObject.Width = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, e.EndTime, timeRange.Value, scrollLength);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var obj in hitObject.NestedHitObjects)
|
foreach (var obj in hitObject.NestedHitObjects)
|
||||||
@ -262,24 +234,16 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
|
|
||||||
private void updatePosition(DrawableHitObject hitObject, double currentTime)
|
private void updatePosition(DrawableHitObject hitObject, double currentTime)
|
||||||
{
|
{
|
||||||
switch (direction.Value)
|
float position = PositionAtTime(hitObject.HitObject.StartTime, currentTime);
|
||||||
{
|
|
||||||
case ScrollingDirection.Up:
|
|
||||||
hitObject.Y = scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, timeRange.Value, scrollLength);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ScrollingDirection.Down:
|
// The position returned from `PositionAtTime` is assuming the `TopLeft` anchor.
|
||||||
hitObject.Y = -scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, timeRange.Value, scrollLength);
|
// A correction is needed because the hit objects are using a different anchor for each direction (e.g. `BottomCentre` for `Bottom` direction).
|
||||||
break;
|
float anchorCorrection = axisInverted ? scrollLength : 0;
|
||||||
|
|
||||||
case ScrollingDirection.Left:
|
if (scrollingAxis == Direction.Horizontal)
|
||||||
hitObject.X = scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, timeRange.Value, scrollLength);
|
hitObject.X = position - anchorCorrection;
|
||||||
break;
|
else
|
||||||
|
hitObject.Y = position - anchorCorrection;
|
||||||
case ScrollingDirection.Right:
|
|
||||||
hitObject.X = -scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, timeRange.Value, scrollLength);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,8 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
private IBindable<WeakReference<ScoreInfo>> itemRemoved;
|
private IBindable<WeakReference<ScoreInfo>> itemRemoved;
|
||||||
|
|
||||||
|
private IBindable<WeakReference<ScoreInfo>> itemAdded;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether to apply the game's currently selected mods as a filter when retrieving scores.
|
/// Whether to apply the game's currently selected mods as a filter when retrieving scores.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -85,6 +87,9 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
itemRemoved = scoreManager.ItemRemoved.GetBoundCopy();
|
itemRemoved = scoreManager.ItemRemoved.GetBoundCopy();
|
||||||
itemRemoved.BindValueChanged(onScoreRemoved);
|
itemRemoved.BindValueChanged(onScoreRemoved);
|
||||||
|
|
||||||
|
itemAdded = scoreManager.ItemUpdated.GetBoundCopy();
|
||||||
|
itemAdded.BindValueChanged(onScoreAdded);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Reset()
|
protected override void Reset()
|
||||||
@ -93,7 +98,25 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
TopScore = null;
|
TopScore = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onScoreRemoved(ValueChangedEvent<WeakReference<ScoreInfo>> score) => Schedule(RefreshScores);
|
private void onScoreRemoved(ValueChangedEvent<WeakReference<ScoreInfo>> score) =>
|
||||||
|
scoreStoreChanged(score);
|
||||||
|
|
||||||
|
private void onScoreAdded(ValueChangedEvent<WeakReference<ScoreInfo>> score) =>
|
||||||
|
scoreStoreChanged(score);
|
||||||
|
|
||||||
|
private void scoreStoreChanged(ValueChangedEvent<WeakReference<ScoreInfo>> score)
|
||||||
|
{
|
||||||
|
if (Scope != BeatmapLeaderboardScope.Local)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (score.NewValue.TryGetTarget(out var scoreInfo))
|
||||||
|
{
|
||||||
|
if (Beatmap?.ID != scoreInfo.BeatmapInfoID)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshScores();
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool IsOnlineScope => Scope != BeatmapLeaderboardScope.Local;
|
protected override bool IsOnlineScope => Scope != BeatmapLeaderboardScope.Local;
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
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.Framework.Input;
|
|
||||||
using osu.Framework.Testing.Input;
|
using osu.Framework.Testing.Input;
|
||||||
using osu.Game.Graphics.Cursor;
|
using osu.Game.Graphics.Cursor;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@ -49,7 +48,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
InputManager = new ManualInputManager
|
InputManager = new ManualInputManager
|
||||||
{
|
{
|
||||||
UseParentInput = true,
|
UseParentInput = true,
|
||||||
Child = new PlatformActionContainer().WithChild(mainContent)
|
Child = mainContent
|
||||||
},
|
},
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
<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="ppy.osu.Framework" Version="2021.611.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2021.614.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.611.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.611.0" />
|
||||||
<PackageReference Include="Sentry" Version="3.4.0" />
|
<PackageReference Include="Sentry" Version="3.4.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.28.2" />
|
<PackageReference Include="SharpCompress" Version="0.28.2" />
|
||||||
|
@ -70,7 +70,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.611.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.614.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.611.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.611.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) -->
|
||||||
@ -93,7 +93,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.611.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2021.614.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.28.2" />
|
<PackageReference Include="SharpCompress" Version="0.28.2" />
|
||||||
<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…
Reference in New Issue
Block a user