diff --git a/osu.Game/Online/Multiplayer/MultiplayerCountdown.cs b/osu.Game/Online/Multiplayer/MultiplayerCountdown.cs index 63bb47b295..81190e64c9 100644 --- a/osu.Game/Online/Multiplayer/MultiplayerCountdown.cs +++ b/osu.Game/Online/Multiplayer/MultiplayerCountdown.cs @@ -5,6 +5,7 @@ using System; using MessagePack; +using osu.Game.Online.Multiplayer.Countdown; namespace osu.Game.Online.Multiplayer { @@ -16,9 +17,12 @@ namespace osu.Game.Online.Multiplayer public abstract class MultiplayerCountdown { /// - /// The time at which the countdown will end. + /// The amount of time remaining in the countdown. /// + /// + /// This is only sent once from the server upon initial retrieval of the or via a . + /// [Key(0)] - public DateTimeOffset EndTime { get; set; } + public TimeSpan TimeRemaining { get; set; } } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/ReadyButton.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/ReadyButton.cs index b37d990466..007e055d8c 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/ReadyButton.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/ReadyButton.cs @@ -34,12 +34,16 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match onRoomUpdated(); } + private MultiplayerCountdown countdown; + private DateTimeOffset countdownReceivedTime; private ScheduledDelegate countdownUpdateDelegate; private void onRoomUpdated() { - updateButtonText(); - updateButtonColour(); + if (countdown == null && room?.Countdown != null) + countdownReceivedTime = DateTimeOffset.Now; + + countdown = room?.Countdown; if (room?.Countdown != null) countdownUpdateDelegate ??= Scheduler.AddDelayed(updateButtonText, 1000, true); @@ -48,6 +52,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match countdownUpdateDelegate?.Cancel(); countdownUpdateDelegate = null; } + + updateButtonText(); + updateButtonColour(); } private void updateButtonText() @@ -64,9 +71,17 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match int countTotal = room.Users.Count(u => u.State != MultiplayerUserState.Spectating); string countText = $"({countReady} / {countTotal} ready)"; - if (room.Countdown != null) + if (countdown != null) { - string countdownText = $"Starting in {room.Countdown.EndTime - DateTimeOffset.Now:mm\\:ss}"; + TimeSpan timeElapsed = DateTimeOffset.Now - countdownReceivedTime; + TimeSpan countdownRemaining; + + if (timeElapsed > countdown.TimeRemaining) + countdownRemaining = TimeSpan.Zero; + else + countdownRemaining = countdown.TimeRemaining - timeElapsed; + + string countdownText = $"Starting in {countdownRemaining:mm\\:ss}"; switch (localUser?.State) { diff --git a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs index 2b03017905..938147e05e 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs @@ -315,7 +315,7 @@ namespace osu.Game.Tests.Visual.Multiplayer var stopSource = countdownStopSource = new CancellationTokenSource(); var finishSource = countdownFinishSource = new CancellationTokenSource(); var cancellationSource = CancellationTokenSource.CreateLinkedTokenSource(stopSource.Token, finishSource.Token); - var countdown = new MatchStartCountdown { EndTime = DateTimeOffset.Now + matchCountdownRequest.Delay }; + var countdown = new MatchStartCountdown { TimeRemaining = matchCountdownRequest.Delay }; Task lastCountdownTask = countdownTask; countdownTask = start();