From 433bb5ae2492aeee65446eb44b29adcd4cfda61c Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 15 Sep 2022 20:54:06 +0900 Subject: [PATCH] Add ServerShuttingDownCountdown --- .../Online/Multiplayer/MultiplayerClient.cs | 26 +++++++++++++++++++ .../Multiplayer/MultiplayerCountdown.cs | 1 + .../ServerShuttingDownCountdown.cs | 20 ++++++++++++++ osu.Game/Online/SignalRWorkaroundTypes.cs | 3 ++- osu.Game/OsuGame.cs | 2 ++ osu.Game/OsuGameBase.cs | 6 ++--- 6 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 osu.Game/Online/Multiplayer/ServerShuttingDownCountdown.cs diff --git a/osu.Game/Online/Multiplayer/MultiplayerClient.cs b/osu.Game/Online/Multiplayer/MultiplayerClient.cs index c398d72118..20efe5662d 100644 --- a/osu.Game/Online/Multiplayer/MultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/MultiplayerClient.cs @@ -18,6 +18,7 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Multiplayer.Countdown; using osu.Game.Online.Rooms; using osu.Game.Online.Rooms.RoomStatuses; +using osu.Game.Overlays.Notifications; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Utils; @@ -26,6 +27,8 @@ namespace osu.Game.Online.Multiplayer { public abstract class MultiplayerClient : Component, IMultiplayerClient, IMultiplayerRoomServer { + public Action? PostNotification { protected get; set; } + /// /// Invoked when any change occurs to the multiplayer room. /// @@ -554,6 +557,14 @@ namespace osu.Game.Online.Multiplayer { case CountdownStartedEvent countdownStartedEvent: Room.ActiveCountdowns.Add(countdownStartedEvent.Countdown); + + switch (countdownStartedEvent.Countdown) + { + case ServerShuttingDownCountdown: + postServerShuttingDownNotification(); + break; + } + break; case CountdownStoppedEvent countdownStoppedEvent: @@ -569,6 +580,21 @@ namespace osu.Game.Online.Multiplayer return Task.CompletedTask; } + private void postServerShuttingDownNotification() + { + ServerShuttingDownCountdown? countdown = room?.ActiveCountdowns.OfType().FirstOrDefault(); + + if (countdown == null) + return; + + PostNotification?.Invoke(new SimpleNotification + { + Text = countdown.FinalNotification + ? $"The multiplayer server is restarting in {countdown.TimeRemaining:hh\\:mm\\:ss}. This multiplayer room will be closed shortly." + : $"The multiplayer server is restarting in {countdown.TimeRemaining:hh\\:mm\\:ss}." + }); + } + Task IMultiplayerClient.UserBeatmapAvailabilityChanged(int userId, BeatmapAvailability beatmapAvailability) { Scheduler.Add(() => diff --git a/osu.Game/Online/Multiplayer/MultiplayerCountdown.cs b/osu.Game/Online/Multiplayer/MultiplayerCountdown.cs index fd22420b99..c59f5937b0 100644 --- a/osu.Game/Online/Multiplayer/MultiplayerCountdown.cs +++ b/osu.Game/Online/Multiplayer/MultiplayerCountdown.cs @@ -13,6 +13,7 @@ namespace osu.Game.Online.Multiplayer [MessagePackObject] [Union(0, typeof(MatchStartCountdown))] // IMPORTANT: Add rules to SignalRUnionWorkaroundResolver for new derived types. [Union(1, typeof(ForceGameplayStartCountdown))] + [Union(2, typeof(ServerShuttingDownCountdown))] public abstract class MultiplayerCountdown { /// diff --git a/osu.Game/Online/Multiplayer/ServerShuttingDownCountdown.cs b/osu.Game/Online/Multiplayer/ServerShuttingDownCountdown.cs new file mode 100644 index 0000000000..4def3acc5e --- /dev/null +++ b/osu.Game/Online/Multiplayer/ServerShuttingDownCountdown.cs @@ -0,0 +1,20 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using MessagePack; + +namespace osu.Game.Online.Multiplayer +{ + /// + /// A countdown that indicates the current multiplayer server is shutting down. + /// + [MessagePackObject] + public class ServerShuttingDownCountdown : MultiplayerCountdown + { + /// + /// If this is the final notification, no more events will be sent after this. + /// + [Key(2)] + public bool FinalNotification { get; set; } + } +} diff --git a/osu.Game/Online/SignalRWorkaroundTypes.cs b/osu.Game/Online/SignalRWorkaroundTypes.cs index 3518fbb4fe..0b545821ee 100644 --- a/osu.Game/Online/SignalRWorkaroundTypes.cs +++ b/osu.Game/Online/SignalRWorkaroundTypes.cs @@ -28,7 +28,8 @@ namespace osu.Game.Online (typeof(TeamVersusRoomState), typeof(MatchRoomState)), (typeof(TeamVersusUserState), typeof(MatchUserState)), (typeof(MatchStartCountdown), typeof(MultiplayerCountdown)), - (typeof(ForceGameplayStartCountdown), typeof(MultiplayerCountdown)) + (typeof(ForceGameplayStartCountdown), typeof(MultiplayerCountdown)), + (typeof(ServerShuttingDownCountdown), typeof(MultiplayerCountdown)), }; } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 9e2384322a..63a46e63d6 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -730,6 +730,8 @@ namespace osu.Game ScoreManager.PostNotification = n => Notifications.Post(n); ScoreManager.PresentImport = items => PresentScore(items.First().Value); + MultiplayerClient.PostNotification = n => Notifications.Post(n); + // make config aware of how to lookup skins for on-screen display purposes. // if this becomes a more common thing, tracked settings should be reconsidered to allow local DI. LocalConfig.LookupSkinName = id => SkinManager.Query(s => s.ID == id)?.ToString() ?? "Unknown"; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index b30a065371..8b016e8eb0 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -179,7 +179,7 @@ namespace osu.Game private SpectatorClient spectatorClient; - private MultiplayerClient multiplayerClient; + protected MultiplayerClient MultiplayerClient { get; private set; } private MetadataClient metadataClient; @@ -284,7 +284,7 @@ namespace osu.Game // TODO: OsuGame or OsuGameBase? dependencies.CacheAs(beatmapUpdater = new BeatmapUpdater(BeatmapManager, difficultyCache, API, Storage)); dependencies.CacheAs(spectatorClient = new OnlineSpectatorClient(endpoints)); - dependencies.CacheAs(multiplayerClient = new OnlineMultiplayerClient(endpoints)); + dependencies.CacheAs(MultiplayerClient = new OnlineMultiplayerClient(endpoints)); dependencies.CacheAs(metadataClient = new OnlineMetadataClient(endpoints)); AddInternal(new BeatmapOnlineChangeIngest(beatmapUpdater, realm, metadataClient)); @@ -329,7 +329,7 @@ namespace osu.Game AddInternal(apiAccess); AddInternal(spectatorClient); - AddInternal(multiplayerClient); + AddInternal(MultiplayerClient); AddInternal(metadataClient); AddInternal(rulesetConfigCache);