diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index 98426e5b7d..d04e63a6b7 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -28,6 +28,7 @@ using osu.Game.Online.Broadcasts; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Metadata; using osu.Game.Online.Multiplayer; using osu.Game.Online.Rooms; using osu.Game.Overlays.Chat; @@ -62,6 +63,9 @@ public partial class StandAloneChatDisplay : CompositeDrawable [Resolved] protected IAPIProvider API { get; private set; } = null!; + [Resolved] + private MetadataClient metadataClient { get; set; } = null!; + [Resolved] protected RulesetStore RulesetStore { get; private set; } = null!; @@ -85,6 +89,8 @@ public partial class StandAloneChatDisplay : CompositeDrawable [Resolved] private OngoingOperationTracker operationTracker { get; set; } = null!; + // private GetUserRequest? userReq; + protected readonly ChatTextBox? TextBox; private ChannelManager? channelManager; @@ -106,6 +112,8 @@ public partial class StandAloneChatDisplay : CompositeDrawable Value = 1250 }; + private IDisposable? userWatchToken; + [Resolved(CanBeNull = true)] // not sure if it actually can be null private ChatTimerHandler? chatTimerHandler { get; set; } @@ -167,6 +175,13 @@ private void load(ChannelManager manager, BeatmapModelDownloader beatmaps, Beatm Scheduler.Add(processMessageQueue); } + protected override void LoadComplete() + { + base.LoadComplete(); + + userWatchToken = metadataClient.BeginWatchingUserPresence(); + } + private void processMessageQueue() { lock (messageQueue) @@ -305,6 +320,7 @@ protected override void Dispose(bool isDisposing) return; Scheduler.Add(() => broadcastServer.Remove(chatBroadcaster)); + userWatchToken?.Dispose(); base.Dispose(isDisposing); } @@ -420,6 +436,11 @@ private void postMessage(TextBox sender, bool newText) break; } } + // special-case player invites + else if (parts[2].StartsWith('#') && int.TryParse(parts[2].AsSpan(1), out numericParam) && parts[1] == @"invite") + { + inviteUserToRoom(numericParam); + } else { switch (parts[1]) @@ -436,6 +457,38 @@ private void postMessage(TextBox sender, bool newText) break; + case @"invite": + // // parameter is a username since it didn't start with `#` + // if (string.IsNullOrEmpty(parts[2])) + // { + // EnqueueBotMessage(@"Invalid username provided"); + // break; + // } + // + // string username = parts[2].Replace('_', ' '); + // + // // check if user is already in the lobby + // var matchingUser = Client.Room?.Users.FirstOrDefault(u => string.Equals(u.User?.Username, username, StringComparison.OrdinalIgnoreCase)); + // + // if (matchingUser != null) + // { + // EnqueueBotMessage($@"User {matchingUser.User?.Username ?? ""} is already in the room!"); + // break; + // } + // + // // try to resolve the username + // userReq?.Cancel(); + // userReq = new GetUserRequest(username); + // userReq.Success += u => inviteUserToRoom(u.Id); + // userReq.Failure += e => + // { + // EnqueueBotMessage($@"Couldn't find user {username}: {e.InnerException?.Message}"); + // }; + // + // API.Queue(userReq); + EnqueueBotMessage("use their user IDs from the sheets please kthx"); + break; + case @"mods": var itemToEdit = Client.Room?.Playlist.SingleOrDefault(i => i.ID == Client.Room?.Settings.PlaylistItemId); @@ -616,6 +669,24 @@ private void postMessage(TextBox sender, bool newText) TextBox.Text = string.Empty; } + private void inviteUserToRoom(int userId) + { + var matchingUser = Client.Room?.Users.FirstOrDefault(u => u.UserID == userId); + + if (matchingUser != null) + { + EnqueueBotMessage($@"User {matchingUser.User?.Username ?? $@"ID {matchingUser.UserID}"} is already in the room!"); + return; + } + + // It's possible the user isn't truly offline, so send the invite anyway. Warn the user in chat though. + EnqueueBotMessage(metadataClient.GetPresence(userId) == null + ? $@"User ID {userId} may be offline, attempting to send an invite anyway." + : $@"Sent an invite to user ID {userId}"); + + Client.InvitePlayer(userId); + } + private async Task postLatestResults(long roomID, PlaylistItem? playlistItem) { if (playlistItem == null) return;