1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-05 13:35:37 +08:00

Add user and panel states

This commit is contained in:
smoogipoo 2021-02-01 17:54:56 +09:00
parent 0909c73ead
commit ac2a995041
9 changed files with 136 additions and 5 deletions

View File

@ -8,6 +8,8 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.OnlinePlay.Multiplayer.Participants; using osu.Game.Screens.OnlinePlay.Multiplayer.Participants;
using osu.Game.Users; using osu.Game.Users;
using osuTK; using osuTK;
@ -123,5 +125,28 @@ namespace osu.Game.Tests.Visual.Multiplayer
} }
}); });
} }
[Test]
public void TestUserWithMods()
{
AddStep("add user", () =>
{
Client.AddUser(new User
{
Id = 0,
Username = $"User 0",
CurrentModeRank = RNG.Next(1, 100000),
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
});
Client.ChangeUserExtraMods(0, new Mod[]
{
new OsuModHardRock(),
new OsuModDifficultyAdjust { ApproachRate = { Value = 1 } }
});
});
AddToggleStep("toggle ready state", v => Client.ChangeUserState(0, v ? MultiplayerUserState.Ready : MultiplayerUserState.Idle));
}
} }
} }

View File

@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Game.Online.API;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
namespace osu.Game.Online.Multiplayer namespace osu.Game.Online.Multiplayer
@ -55,6 +57,8 @@ namespace osu.Game.Online.Multiplayer
/// <param name="beatmapAvailability">The new beatmap availability state of the user.</param> /// <param name="beatmapAvailability">The new beatmap availability state of the user.</param>
Task UserBeatmapAvailabilityChanged(int userId, BeatmapAvailability beatmapAvailability); Task UserBeatmapAvailabilityChanged(int userId, BeatmapAvailability beatmapAvailability);
Task UserExtraModsChanged(int userId, IEnumerable<APIMod> mods);
/// <summary> /// <summary>
/// Signals that a match is to be started. This will *only* be sent to clients which are to begin loading at this point. /// Signals that a match is to be started. This will *only* be sent to clients which are to begin loading at this point.
/// </summary> /// </summary>

View File

@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Game.Online.API;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
namespace osu.Game.Online.Multiplayer namespace osu.Game.Online.Multiplayer
@ -47,6 +49,8 @@ namespace osu.Game.Online.Multiplayer
/// <param name="newBeatmapAvailability">The proposed new beatmap availability state.</param> /// <param name="newBeatmapAvailability">The proposed new beatmap availability state.</param>
Task ChangeBeatmapAvailability(BeatmapAvailability newBeatmapAvailability); Task ChangeBeatmapAvailability(BeatmapAvailability newBeatmapAvailability);
Task ChangeExtraMods(IEnumerable<APIMod> newMods);
/// <summary> /// <summary>
/// As the host of a room, start the match. /// As the host of a room, start the match.
/// </summary> /// </summary>

View File

@ -4,7 +4,11 @@
#nullable enable #nullable enable
using System; using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using Newtonsoft.Json; using Newtonsoft.Json;
using osu.Game.Online.API;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Users; using osu.Game.Users;
@ -22,6 +26,9 @@ namespace osu.Game.Online.Multiplayer
/// </summary> /// </summary>
public BeatmapAvailability BeatmapAvailability { get; set; } = BeatmapAvailability.LocallyAvailable(); public BeatmapAvailability BeatmapAvailability { get; set; } = BeatmapAvailability.LocallyAvailable();
[NotNull]
public IEnumerable<APIMod> ExtraMods { get; set; } = Enumerable.Empty<APIMod>();
public User? User { get; set; } public User? User { get; set; }
[JsonConstructor] [JsonConstructor]

View File

@ -22,6 +22,7 @@ using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Online.Rooms.RoomStatuses; using osu.Game.Online.Rooms.RoomStatuses;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Users; using osu.Game.Users;
using osu.Game.Utils; using osu.Game.Utils;
@ -231,6 +232,10 @@ namespace osu.Game.Online.Multiplayer
public abstract Task ChangeBeatmapAvailability(BeatmapAvailability newBeatmapAvailability); public abstract Task ChangeBeatmapAvailability(BeatmapAvailability newBeatmapAvailability);
public Task ChangeExtraMods(IEnumerable<Mod> newMods) => ChangeExtraMods(newMods.Select(m => new APIMod(m)).ToList());
public abstract Task ChangeExtraMods(IEnumerable<APIMod> newMods);
public abstract Task StartMatch(); public abstract Task StartMatch();
Task IMultiplayerClient.RoomStateChanged(MultiplayerRoomState state) Task IMultiplayerClient.RoomStateChanged(MultiplayerRoomState state)
@ -379,6 +384,27 @@ namespace osu.Game.Online.Multiplayer
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task UserExtraModsChanged(int userId, IEnumerable<APIMod> mods)
{
if (Room == null)
return Task.CompletedTask;
Scheduler.Add(() =>
{
var user = Room?.Users.SingleOrDefault(u => u.UserID == userId);
// errors here are not critical - user mods is mostly for display.
if (user == null)
return;
user.ExtraMods = mods;
RoomUpdated?.Invoke();
}, false);
return Task.CompletedTask;
}
Task IMultiplayerClient.LoadRequested() Task IMultiplayerClient.LoadRequested()
{ {
if (Room == null) if (Room == null)

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@ -15,6 +16,7 @@ using osu.Game.Extensions;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Overlays.Mods; using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.OnlinePlay.Components; using osu.Game.Screens.OnlinePlay.Components;
using osu.Game.Screens.OnlinePlay.Match; using osu.Game.Screens.OnlinePlay.Match;
using osu.Game.Screens.OnlinePlay.Match.Components; using osu.Game.Screens.OnlinePlay.Match.Components;
@ -240,6 +242,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
base.LoadComplete(); base.LoadComplete();
Playlist.BindCollectionChanged(onPlaylistChanged, true); Playlist.BindCollectionChanged(onPlaylistChanged, true);
ExtraMods.BindValueChanged(onExtraModsChanged);
client.LoadRequested += onLoadRequested; client.LoadRequested += onLoadRequested;
@ -285,6 +288,14 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
} }
} }
private void onExtraModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> extraMods)
{
if (client.Room == null)
return;
client.ChangeExtraMods(extraMods.NewValue).CatchUnobservedExceptions();
}
private void onReadyClick() private void onReadyClick()
{ {
Debug.Assert(readyClickOperation == null); Debug.Assert(readyClickOperation == null);

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -16,6 +17,8 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Rulesets;
using osu.Game.Screens.Play.HUD;
using osu.Game.Users; using osu.Game.Users;
using osu.Game.Users.Drawables; using osu.Game.Users.Drawables;
using osuTK; using osuTK;
@ -30,6 +33,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
[Resolved] [Resolved]
private IAPIProvider api { get; set; } private IAPIProvider api { get; set; }
[Resolved]
private RulesetStore rulesets { get; set; }
private ModDisplay extraModsDisplay;
private StateDisplay userStateDisplay; private StateDisplay userStateDisplay;
private SpriteIcon crown; private SpriteIcon crown;
@ -122,11 +129,32 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
} }
} }
}, },
userStateDisplay = new StateDisplay new FillFlowContainer
{ {
Anchor = Anchor.CentreRight, Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight, Origin = Anchor.CentreRight,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Margin = new MarginPadding { Right = 10 }, Margin = new MarginPadding { Right = 10 },
Spacing = new Vector2(10),
Children = new Drawable[]
{
extraModsDisplay = new ModDisplay
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(0.5f),
ExpansionMode = ExpansionMode.AlwaysContracted,
DisplayUnrankedText = false,
ExpandOnAppear = false
},
userStateDisplay = new StateDisplay
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
AlwaysPresent = true
}
}
} }
} }
} }
@ -143,7 +171,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
const double fade_time = 50; const double fade_time = 50;
var ruleset = rulesets.GetRuleset(Room.Settings.RulesetID).CreateInstance();
userStateDisplay.Status = User.State; userStateDisplay.Status = User.State;
extraModsDisplay.Current.Value = User.ExtraMods.Select(m => m.ToMod(ruleset)).ToList();
if (Room.Host?.Equals(User) == true) if (Room.Host?.Equals(User) == true)
crown.FadeIn(fade_time); crown.FadeIn(fade_time);

View File

@ -26,6 +26,8 @@ namespace osu.Game.Screens.Play.HUD
public ExpansionMode ExpansionMode = ExpansionMode.ExpandOnHover; public ExpansionMode ExpansionMode = ExpansionMode.ExpandOnHover;
public bool ExpandOnAppear = true;
private readonly Bindable<IReadOnlyList<Mod>> current = new Bindable<IReadOnlyList<Mod>>(); private readonly Bindable<IReadOnlyList<Mod>> current = new Bindable<IReadOnlyList<Mod>>();
public Bindable<IReadOnlyList<Mod>> Current public Bindable<IReadOnlyList<Mod>> Current
@ -108,10 +110,14 @@ namespace osu.Game.Screens.Play.HUD
else else
unrankedText.Hide(); unrankedText.Hide();
expand(); if (ExpandOnAppear)
{
using (iconsContainer.BeginDelayedSequence(1200)) expand();
contract(); using (iconsContainer.BeginDelayedSequence(1200))
contract();
}
else
iconsContainer.TransformSpacingTo(new Vector2(-25, 0));
} }
private void expand() private void expand()

View File

@ -3,6 +3,7 @@
#nullable enable #nullable enable
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -11,6 +12,7 @@ using osu.Framework.Bindables;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms; using osu.Game.Online.Rooms;
using osu.Game.Rulesets.Mods;
using osu.Game.Users; using osu.Game.Users;
namespace osu.Game.Tests.Visual.Multiplayer namespace osu.Game.Tests.Visual.Multiplayer
@ -122,6 +124,21 @@ namespace osu.Game.Tests.Visual.Multiplayer
return Task.CompletedTask; return Task.CompletedTask;
} }
public void ChangeUserExtraMods(int userId, IEnumerable<Mod> newMods)
=> ChangeUserExtraMods(userId, newMods.Select(m => new APIMod(m)).ToList());
public void ChangeUserExtraMods(int userId, IEnumerable<APIMod> newMods)
{
Debug.Assert(Room != null);
((IMultiplayerClient)this).UserExtraModsChanged(userId, newMods.ToList());
}
public override Task ChangeExtraMods(IEnumerable<APIMod> newMods)
{
ChangeUserExtraMods(api.LocalUser.Value.Id, newMods);
return Task.CompletedTask;
}
public override Task StartMatch() public override Task StartMatch()
{ {
Debug.Assert(Room != null); Debug.Assert(Room != null);