1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-18 15:30:06 +08:00
Files
osu-lazer/osu.Game/Screens/OnlinePlay/Matchmaking/MatchmakingController.cs
T
2025-09-07 16:17:27 +09:00

165 lines
5.4 KiB
C#

// 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 osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Screens;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens;
namespace osu.Game.Screens.OnlinePlay.Matchmaking
{
public partial class MatchmakingController : Component
{
public readonly Bindable<MatchmakingQueueScreen.MatchmakingScreenState> CurrentState = new Bindable<MatchmakingQueueScreen.MatchmakingScreenState>();
[Resolved]
private MultiplayerClient client { get; set; } = null!;
[Resolved]
private INotificationOverlay? notifications { get; set; }
[Resolved]
private IPerformFromScreenRunner? performer { get; set; }
private ProgressNotification? backgroundNotification;
private Notification? readyNotification;
private bool isBackgrounded;
protected override void LoadComplete()
{
base.LoadComplete();
client.RoomUpdated += onRoomUpdated;
client.MatchmakingQueueJoined += onMatchmakingQueueJoined;
client.MatchmakingQueueLeft += onMatchmakingQueueLeft;
client.MatchmakingRoomInvited += onMatchmakingRoomInvited;
client.MatchmakingRoomReady += onMatchmakingRoomReady;
}
public void SearchInBackground()
{
if (isBackgrounded)
return;
isBackgrounded = true;
postNotification();
}
public void SearchInForeground()
{
if (!isBackgrounded)
return;
isBackgrounded = false;
closeNotifications();
}
private void onRoomUpdated() => Scheduler.Add(() =>
{
if (client.Room == null)
CurrentState.Value = MatchmakingQueueScreen.MatchmakingScreenState.Idle;
});
private void onMatchmakingQueueJoined() => Scheduler.Add(() =>
{
CurrentState.Value = MatchmakingQueueScreen.MatchmakingScreenState.Queueing;
if (isBackgrounded)
{
closeNotifications();
postNotification();
}
});
private void onMatchmakingQueueLeft() => Scheduler.Add(() =>
{
if (CurrentState.Value != MatchmakingQueueScreen.MatchmakingScreenState.InRoom)
CurrentState.Value = MatchmakingQueueScreen.MatchmakingScreenState.Idle;
closeNotifications();
});
private void onMatchmakingRoomInvited() => Scheduler.Add(() =>
{
CurrentState.Value = MatchmakingQueueScreen.MatchmakingScreenState.PendingAccept;
if (backgroundNotification != null)
{
backgroundNotification.State = ProgressNotificationState.Completed;
backgroundNotification = null;
}
});
private void onMatchmakingRoomReady(long roomId, string password) => Scheduler.Add(() =>
{
client.JoinRoom(new Room { RoomID = roomId }, password)
.FireAndForget(() => Scheduler.Add(() =>
{
CurrentState.Value = MatchmakingQueueScreen.MatchmakingScreenState.InRoom;
}));
});
private void postNotification()
{
if (backgroundNotification != null)
return;
notifications?.Post(backgroundNotification = new ProgressNotification
{
Text = "Searching for opponents...",
CompletionTarget = n => notifications.Post(readyNotification = n),
CompletionText = "Your match is ready! Click to join.",
CompletionClickAction = () =>
{
client.MatchmakingAcceptInvitation().FireAndForget();
performer?.PerformFromScreen(s => s.Push(new MatchmakingIntroScreen()));
closeNotifications();
return true;
},
CancelRequested = () =>
{
client.MatchmakingLeaveQueue().FireAndForget();
closeNotifications();
return true;
}
});
}
private void closeNotifications()
{
if (backgroundNotification != null)
{
backgroundNotification.State = ProgressNotificationState.Cancelled;
backgroundNotification.Close(false);
}
readyNotification?.Close(false);
backgroundNotification = null;
readyNotification = null;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (client.IsNotNull())
{
client.RoomUpdated -= onRoomUpdated;
client.MatchmakingQueueJoined -= onMatchmakingQueueJoined;
client.MatchmakingQueueLeft -= onMatchmakingQueueLeft;
client.MatchmakingRoomInvited -= onMatchmakingRoomInvited;
client.MatchmakingRoomReady -= onMatchmakingRoomReady;
}
}
}
}