Merge pull request #20145 from smoogipoo/multiple-countdowns

Implement support for multiple active countdowns in multiplayer
This commit is contained in:
Dean Herbert
2022-09-08 19:15:30 +09:00
committed by GitHub
15 changed files with 124 additions and 56 deletions

View File

@ -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 MessagePack;
namespace osu.Game.Online.Multiplayer.Countdown
{
/// <summary>
/// Indicates a change to the <see cref="MultiplayerRoom"/>'s countdown.
/// </summary>
[MessagePackObject]
public class CountdownChangedEvent : MatchServerEvent
{
/// <summary>
/// The new countdown.
/// </summary>
[Key(0)]
public MultiplayerCountdown? Countdown { get; set; }
}
}

View File

@ -0,0 +1,28 @@
// 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 MessagePack;
using Newtonsoft.Json;
namespace osu.Game.Online.Multiplayer.Countdown
{
/// <summary>
/// Indicates that a countdown started in the <see cref="MultiplayerRoom"/>.
/// </summary>
[MessagePackObject]
public class CountdownStartedEvent : MatchServerEvent
{
/// <summary>
/// The countdown that was started.
/// </summary>
[Key(0)]
public readonly MultiplayerCountdown Countdown;
[JsonConstructor]
[SerializationConstructor]
public CountdownStartedEvent(MultiplayerCountdown countdown)
{
Countdown = countdown;
}
}
}

View File

@ -0,0 +1,28 @@
// 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 MessagePack;
using Newtonsoft.Json;
namespace osu.Game.Online.Multiplayer.Countdown
{
/// <summary>
/// Indicates that a countdown was stopped in the <see cref="MultiplayerRoom"/>.
/// </summary>
[MessagePackObject]
public class CountdownStoppedEvent : MatchServerEvent
{
/// <summary>
/// The identifier of the countdown that was stopped.
/// </summary>
[Key(0)]
public readonly int ID;
[JsonConstructor]
[SerializationConstructor]
public CountdownStoppedEvent(int id)
{
ID = id;
}
}
}

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using MessagePack;
using Newtonsoft.Json;
namespace osu.Game.Online.Multiplayer.Countdown
{
@ -11,5 +12,14 @@ namespace osu.Game.Online.Multiplayer.Countdown
[MessagePackObject]
public class StopCountdownRequest : MatchUserRequest
{
[Key(0)]
public readonly int ID;
[JsonConstructor]
[SerializationConstructor]
public StopCountdownRequest(int id)
{
ID = id;
}
}
}

View File

@ -13,7 +13,7 @@ namespace osu.Game.Online.Multiplayer
/// and forcing progression of any clients that are blocking load due to user interaction.
/// </summary>
[MessagePackObject]
public class ForceGameplayStartCountdown : MultiplayerCountdown
public sealed class ForceGameplayStartCountdown : MultiplayerCountdown
{
}
}

View File

@ -13,7 +13,8 @@ namespace osu.Game.Online.Multiplayer
[Serializable]
[MessagePackObject]
// IMPORTANT: Add rules to SignalRUnionWorkaroundResolver for new derived types.
[Union(0, typeof(CountdownChangedEvent))]
[Union(0, typeof(CountdownStartedEvent))]
[Union(1, typeof(CountdownStoppedEvent))]
public abstract class MatchServerEvent
{
}

View File

@ -9,7 +9,7 @@ namespace osu.Game.Online.Multiplayer
/// A <see cref="MultiplayerCountdown"/> which will start the match after ending.
/// </summary>
[MessagePackObject]
public class MatchStartCountdown : MultiplayerCountdown
public sealed class MatchStartCountdown : MultiplayerCountdown
{
}
}

View File

@ -552,8 +552,14 @@ namespace osu.Game.Online.Multiplayer
switch (e)
{
case CountdownChangedEvent countdownChangedEvent:
Room.Countdown = countdownChangedEvent.Countdown;
case CountdownStartedEvent countdownStartedEvent:
Room.ActiveCountdowns.Add(countdownStartedEvent.Countdown);
break;
case CountdownStoppedEvent countdownStoppedEvent:
MultiplayerCountdown? countdown = Room.ActiveCountdowns.FirstOrDefault(countdown => countdown.ID == countdownStoppedEvent.ID);
if (countdown != null)
Room.ActiveCountdowns.Remove(countdown);
break;
}

View File

@ -15,13 +15,24 @@ namespace osu.Game.Online.Multiplayer
[Union(1, typeof(ForceGameplayStartCountdown))]
public abstract class MultiplayerCountdown
{
/// <summary>
/// A unique identifier for this countdown.
/// </summary>
[Key(0)]
public int ID { get; set; }
/// <summary>
/// The amount of time remaining in the countdown.
/// </summary>
/// <remarks>
/// This is only sent once from the server upon initial retrieval of the <see cref="MultiplayerRoom"/> or via a <see cref="CountdownChangedEvent"/>.
/// This is only sent once from the server upon initial retrieval of the <see cref="MultiplayerRoom"/> or via a <see cref="CountdownStartedEvent"/>.
/// </remarks>
[Key(0)]
[Key(1)]
public TimeSpan TimeRemaining { get; set; }
/// <summary>
/// Whether only a single instance of this <see cref="MultiplayerCountdown"/> type may be active at any one time.
/// </summary>
public virtual bool IsExclusive => true;
}
}

View File

@ -53,10 +53,10 @@ namespace osu.Game.Online.Multiplayer
public IList<MultiplayerPlaylistItem> Playlist { get; set; } = new List<MultiplayerPlaylistItem>();
/// <summary>
/// The currently-running countdown.
/// The currently running countdowns.
/// </summary>
[Key(7)]
public MultiplayerCountdown? Countdown { get; set; }
public IList<MultiplayerCountdown> ActiveCountdowns { get; set; } = new List<MultiplayerCountdown>();
[JsonConstructor]
[SerializationConstructor]

View File

@ -23,7 +23,8 @@ namespace osu.Game.Online
(typeof(ChangeTeamRequest), typeof(MatchUserRequest)),
(typeof(StartMatchCountdownRequest), typeof(MatchUserRequest)),
(typeof(StopCountdownRequest), typeof(MatchUserRequest)),
(typeof(CountdownChangedEvent), typeof(MatchServerEvent)),
(typeof(CountdownStartedEvent), typeof(MatchServerEvent)),
(typeof(CountdownStoppedEvent), typeof(MatchServerEvent)),
(typeof(TeamVersusRoomState), typeof(MatchRoomState)),
(typeof(TeamVersusUserState), typeof(MatchUserState)),
(typeof(MatchStartCountdown), typeof(MultiplayerCountdown)),