mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 09:27:29 +08:00
Merge pull request #18353 from frenzibyte/spectator-catch-up-work-alt
Disallow multi-spectator player clocks from being started/stopped externally
This commit is contained in:
commit
7d0470794b
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
@ -15,13 +16,14 @@ using osu.Game.Configuration;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Screens.Play.PlayerSettings;
|
||||
using osu.Game.Storyboards;
|
||||
using osu.Game.Tests.Beatmaps.IO;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
@ -349,15 +351,27 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests spectating with a gameplay start time set to a negative value.
|
||||
/// Simulating beatmaps with high <see cref="BeatmapInfo.AudioLeadIn"/> or negative time storyboard elements.
|
||||
/// Tests spectating with a beatmap that has a high <see cref="BeatmapInfo.AudioLeadIn"/> value.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestNegativeGameplayStartTime()
|
||||
public void TestAudioLeadIn() => testLeadIn(b => b.BeatmapInfo.AudioLeadIn = 2000);
|
||||
|
||||
/// <summary>
|
||||
/// Tests spectating with a beatmap that has a storyboard element with a negative start time (i.e. intro storyboard element).
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestIntroStoryboardElement() => testLeadIn(b =>
|
||||
{
|
||||
var sprite = new StoryboardSprite("unknown", Anchor.TopLeft, Vector2.Zero);
|
||||
sprite.TimelineGroup.Alpha.Add(Easing.None, -2000, 0, 0, 1);
|
||||
b.Storyboard.GetLayer("Background").Add(sprite);
|
||||
});
|
||||
|
||||
private void testLeadIn(Action<WorkingBeatmap> applyToBeatmap = null)
|
||||
{
|
||||
start(PLAYER_1_ID);
|
||||
|
||||
loadSpectateScreen(false, -500);
|
||||
loadSpectateScreen(false, applyToBeatmap);
|
||||
|
||||
// to ensure negative gameplay start time does not affect spectator, send frames exactly after StartGameplay().
|
||||
// (similar to real spectating sessions in which the first frames get sent between StartGameplay() and player load complete)
|
||||
@ -371,14 +385,16 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
assertRunning(PLAYER_1_ID);
|
||||
}
|
||||
|
||||
private void loadSpectateScreen(bool waitForPlayerLoad = true, double? gameplayStartTime = null)
|
||||
private void loadSpectateScreen(bool waitForPlayerLoad = true, Action<WorkingBeatmap> applyToBeatmap = null)
|
||||
{
|
||||
AddStep(!gameplayStartTime.HasValue ? "load screen" : $"load screen (start = {gameplayStartTime}ms)", () =>
|
||||
AddStep("load screen", () =>
|
||||
{
|
||||
Beatmap.Value = beatmapManager.GetWorkingBeatmap(importedBeatmap);
|
||||
Ruleset.Value = importedBeatmap.Ruleset;
|
||||
|
||||
LoadScreen(spectatorScreen = new TestMultiSpectatorScreen(SelectedRoom.Value, playingUsers.ToArray(), gameplayStartTime));
|
||||
applyToBeatmap?.Invoke(Beatmap.Value);
|
||||
|
||||
LoadScreen(spectatorScreen = new MultiSpectatorScreen(SelectedRoom.Value, playingUsers.ToArray()));
|
||||
});
|
||||
|
||||
AddUntilStep("wait for screen load", () => spectatorScreen.LoadState == LoadState.Loaded && (!waitForPlayerLoad || spectatorScreen.AllPlayersLoaded));
|
||||
@ -461,19 +477,5 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
private GameplayLeaderboardScore getLeaderboardScore(int userId) => spectatorScreen.ChildrenOfType<GameplayLeaderboardScore>().Single(s => s.User?.Id == userId);
|
||||
|
||||
private int[] getPlayerIds(int count) => Enumerable.Range(PLAYER_1_ID, count).ToArray();
|
||||
|
||||
private class TestMultiSpectatorScreen : MultiSpectatorScreen
|
||||
{
|
||||
private readonly double? startTime;
|
||||
|
||||
public TestMultiSpectatorScreen(Room room, MultiplayerRoomUser[] users, double? startTime = null)
|
||||
: base(room, users)
|
||||
{
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
protected override MasterGameplayClockContainer CreateMasterGameplayClockContainer(WorkingBeatmap beatmap)
|
||||
=> new MasterGameplayClockContainer(beatmap, 0) { StartTime = startTime ?? 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,16 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
|
||||
|
||||
public void Stop() => IsRunning = false;
|
||||
|
||||
void IAdjustableClock.Start()
|
||||
{
|
||||
// Our running state should only be managed by an ISyncManager, ignore calls from external sources.
|
||||
}
|
||||
|
||||
void IAdjustableClock.Stop()
|
||||
{
|
||||
// Our running state should only be managed by an ISyncManager, ignore calls from external sources.
|
||||
}
|
||||
|
||||
public bool Seek(double position)
|
||||
{
|
||||
CurrentTime = position;
|
||||
|
@ -144,6 +144,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
|
||||
// Make sure the player clock is running if it can.
|
||||
if (!clock.WaitingOnFrames.Value)
|
||||
clock.Start();
|
||||
else
|
||||
clock.Stop();
|
||||
|
||||
if (clock.IsCatchingUp)
|
||||
{
|
||||
|
@ -11,6 +11,16 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
|
||||
/// </summary>
|
||||
public interface ISpectatorPlayerClock : IFrameBasedClock, IAdjustableClock
|
||||
{
|
||||
/// <summary>
|
||||
/// Starts this <see cref="ISpectatorPlayerClock"/>.
|
||||
/// </summary>
|
||||
new void Start();
|
||||
|
||||
/// <summary>
|
||||
/// Stops this <see cref="ISpectatorPlayerClock"/>.
|
||||
/// </summary>
|
||||
new void Stop();
|
||||
|
||||
/// <summary>
|
||||
/// Whether this clock is waiting on frames to continue playback.
|
||||
/// </summary>
|
||||
|
Loading…
Reference in New Issue
Block a user