Add basic beatmap download and play flow

This commit is contained in:
Dean Herbert 2020-10-27 19:23:35 +09:00
parent 42b3aa3359
commit 2cacdaa11b
2 changed files with 96 additions and 11 deletions

View File

@ -25,6 +25,9 @@ namespace osu.Game.Tests.Visual.Gameplay
[Cached(typeof(SpectatorStreamingClient))]
private TestSpectatorStreamingClient testSpectatorStreamingClient = new TestSpectatorStreamingClient();
// used just to show beatmap card for the time being.
protected override bool UseOnlineAPI => true;
private Spectator spectatorScreen;
[Resolved]
@ -134,9 +137,9 @@ namespace osu.Game.Tests.Visual.Gameplay
start();
sendFrames();
waitForPlayer();
// should immediately exit and unbind from streaming client
AddStep("stop spectating", () => (Stack.CurrentScreen as Player)?.Exit());
AddUntilStep("spectating stopped", () => spectatorScreen.GetParentScreen() == null);
}
@ -145,14 +148,15 @@ namespace osu.Game.Tests.Visual.Gameplay
{
loadSpectatingScreen();
start();
start(88);
sendFrames();
// player should never arrive.
AddAssert("screen didn't change", () => Stack.CurrentScreen is Spectator);
}
private void waitForPlayer() => AddUntilStep("wait for player", () => Stack.CurrentScreen is Player);
private void start() => AddStep("start play", () => testSpectatorStreamingClient.StartPlay());
private void start(int? beatmapId = null) => AddStep("start play", () => testSpectatorStreamingClient.StartPlay(beatmapId));
private void checkPaused(bool state) =>
AddAssert($"game is {(state ? "paused" : "playing")}", () => player.ChildrenOfType<DrawableRuleset>().First().IsPaused.Value == state);
@ -176,7 +180,7 @@ namespace osu.Game.Tests.Visual.Gameplay
public readonly User StreamingUser = new User { Id = 1234, Username = "Test user" };
public void StartPlay() => sendState();
public void StartPlay(int? beatmapId = null) => sendState(beatmapId);
public void EndPlay()
{
@ -218,12 +222,12 @@ namespace osu.Game.Tests.Visual.Gameplay
base.WatchUser(userId);
}
private void sendState()
private void sendState(int? beatmapId = null)
{
sentState = true;
((ISpectatorClient)this).UserBeganPlaying((int)StreamingUser.Id, new SpectatorState
{
BeatmapID = beatmaps.GetAllUsableBeatmapSets().First().Beatmaps.First(b => b.RulesetID == 0).OnlineBeatmapID,
BeatmapID = beatmapId ?? beatmaps.GetAllUsableBeatmapSets().First().Beatmaps.First(b => b.RulesetID == 0).OnlineBeatmapID,
RulesetID = 0,
});
}

View File

@ -8,10 +8,15 @@ using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.Spectator;
using osu.Game.Overlays.BeatmapListing.Panels;
using osu.Game.Replays;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
@ -19,6 +24,7 @@ using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Replays.Types;
using osu.Game.Scoring;
using osu.Game.Users;
using osuTK;
namespace osu.Game.Screens.Play
{
@ -35,6 +41,9 @@ namespace osu.Game.Screens.Play
[Resolved]
private Bindable<IReadOnlyList<Mod>> mods { get; set; }
[Resolved]
private IAPIProvider api { get; set; }
[Resolved]
private SpectatorStreamingClient spectatorStreaming { get; set; }
@ -46,6 +55,12 @@ namespace osu.Game.Screens.Play
private Replay replay;
private Container beatmapPanelContainer;
private SpectatorState state;
private IBindable<WeakReference<BeatmapSetInfo>> managerUpdated;
public Spectator([NotNull] User targetUser)
{
this.targetUser = targetUser ?? throw new ArgumentNullException(nameof(targetUser));
@ -56,11 +71,42 @@ namespace osu.Game.Screens.Play
{
InternalChildren = new Drawable[]
{
new OsuSpriteText
new FillFlowContainer
{
Text = $"Watching {targetUser}",
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Spacing = new Vector2(15),
Children = new Drawable[]
{
new OsuSpriteText
{
Text = "Currently spectating",
Font = OsuFont.Default.With(size: 30),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
new UserGridPanel(targetUser)
{
Width = 290,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
new OsuSpriteText
{
Text = "playing",
Font = OsuFont.Default.With(size: 30),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
beatmapPanelContainer = new Container
{
AutoSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
}
},
};
}
@ -74,6 +120,15 @@ namespace osu.Game.Screens.Play
spectatorStreaming.OnNewFrames += userSentFrames;
spectatorStreaming.WatchUser((int)targetUser.Id);
managerUpdated = beatmaps.ItemUpdated.GetBoundCopy();
managerUpdated.BindValueChanged(beatmapUpdated);
}
private void beatmapUpdated(ValueChangedEvent<WeakReference<BeatmapSetInfo>> beatmap)
{
if (beatmap.NewValue.TryGetTarget(out var beatmapSet) && beatmapSet.Beatmaps.Any(b => b.OnlineBeatmapID == state.BeatmapID))
attemptStart();
}
private void userSentFrames(int userId, FrameDataBundle data)
@ -107,16 +162,31 @@ namespace osu.Game.Screens.Play
replay ??= new Replay { HasReceivedAllFrames = false };
this.state = state;
attemptStart();
}
private void attemptStart()
{
var resolvedRuleset = rulesets.AvailableRulesets.FirstOrDefault(r => r.ID == state.RulesetID)?.CreateInstance();
// ruleset not available
if (resolvedRuleset == null)
return;
if (state.BeatmapID == null)
return;
this.MakeCurrent();
var resolvedBeatmap = beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == state.BeatmapID);
if (resolvedBeatmap == null)
{
showBeatmapPanel(state.BeatmapID.Value);
return;
}
var scoreInfo = new ScoreInfo
{
@ -125,8 +195,6 @@ namespace osu.Game.Screens.Play
Ruleset = resolvedRuleset.RulesetInfo,
};
this.MakeCurrent();
ruleset.Value = resolvedRuleset.RulesetInfo;
beatmap.Value = beatmaps.GetWorkingBeatmap(resolvedBeatmap);
@ -137,6 +205,17 @@ namespace osu.Game.Screens.Play
}));
}
private void showBeatmapPanel(int beatmapId)
{
var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId);
req.Success += res => Schedule(() =>
{
beatmapPanelContainer.Child = new GridBeatmapPanel(res.ToBeatmapSet(rulesets));
});
api.Queue(req);
}
private void userFinishedPlaying(int userId, SpectatorState state)
{
if (replay == null) return;
@ -156,6 +235,8 @@ namespace osu.Game.Screens.Play
spectatorStreaming.StopWatchingUser((int)targetUser.Id);
}
managerUpdated.UnbindAll();
}
}
}