mirror of
https://github.com/ppy/osu
synced 2024-12-17 04:15:37 +00:00
Merge pull request #11708 from frenzibyte/multiplayer-participant-rank
Display user global rank for multiplayer room participants
This commit is contained in:
commit
b8c1e8ed7a
@ -105,7 +105,7 @@ namespace osu.Desktop
|
|||||||
if (privacyMode.Value == DiscordRichPresenceMode.Limited)
|
if (privacyMode.Value == DiscordRichPresenceMode.Limited)
|
||||||
presence.Assets.LargeImageText = string.Empty;
|
presence.Assets.LargeImageText = string.Empty;
|
||||||
else
|
else
|
||||||
presence.Assets.LargeImageText = $"{user.Value.Username}" + (user.Value.Statistics?.Ranks.Global > 0 ? $" (rank #{user.Value.Statistics.Ranks.Global:N0})" : string.Empty);
|
presence.Assets.LargeImageText = $"{user.Value.Username}" + (user.Value.Statistics?.GlobalRank > 0 ? $" (rank #{user.Value.Statistics.GlobalRank:N0})" : string.Empty);
|
||||||
|
|
||||||
// update ruleset
|
// update ruleset
|
||||||
presence.Assets.SmallImageKey = ruleset.Value.ID <= 3 ? $"mode_{ruleset.Value.ID}" : "mode_custom";
|
presence.Assets.SmallImageKey = ruleset.Value.ID <= 3 ? $"mode_{ruleset.Value.ID}" : "mode_custom";
|
||||||
|
@ -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.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -155,7 +156,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
Id = i,
|
Id = i,
|
||||||
Username = $"User {i}",
|
Username = $"User {i}",
|
||||||
CurrentModeRank = RNG.Next(1, 100000),
|
RulesetsStatistics = new Dictionary<string, UserStatistics>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Ruleset.Value.ShortName,
|
||||||
|
new UserStatistics { GlobalRank = RNG.Next(1, 100000), }
|
||||||
|
}
|
||||||
|
},
|
||||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
|
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -193,7 +200,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
Id = 0,
|
Id = 0,
|
||||||
Username = "User 0",
|
Username = "User 0",
|
||||||
CurrentModeRank = RNG.Next(1, 100000),
|
RulesetsStatistics = new Dictionary<string, UserStatistics>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Ruleset.Value.ShortName,
|
||||||
|
new UserStatistics { GlobalRank = RNG.Next(1, 100000), }
|
||||||
|
}
|
||||||
|
},
|
||||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
|
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
graph.Statistics.Value = new UserStatistics
|
graph.Statistics.Value = new UserStatistics
|
||||||
{
|
{
|
||||||
Ranks = new UserStatistics.UserRanks { Global = 123456 },
|
GlobalRank = 123456,
|
||||||
PP = 12345,
|
PP = 12345,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -79,7 +79,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
graph.Statistics.Value = new UserStatistics
|
graph.Statistics.Value = new UserStatistics
|
||||||
{
|
{
|
||||||
Ranks = new UserStatistics.UserRanks { Global = 89000 },
|
GlobalRank = 89000,
|
||||||
PP = 12345,
|
PP = 12345,
|
||||||
RankHistory = new User.RankHistoryData
|
RankHistory = new User.RankHistoryData
|
||||||
{
|
{
|
||||||
@ -92,7 +92,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
graph.Statistics.Value = new UserStatistics
|
graph.Statistics.Value = new UserStatistics
|
||||||
{
|
{
|
||||||
Ranks = new UserStatistics.UserRanks { Global = 89000 },
|
GlobalRank = 89000,
|
||||||
PP = 12345,
|
PP = 12345,
|
||||||
RankHistory = new User.RankHistoryData
|
RankHistory = new User.RankHistoryData
|
||||||
{
|
{
|
||||||
@ -105,7 +105,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
graph.Statistics.Value = new UserStatistics
|
graph.Statistics.Value = new UserStatistics
|
||||||
{
|
{
|
||||||
Ranks = new UserStatistics.UserRanks { Global = 12000 },
|
GlobalRank = 12000,
|
||||||
PP = 12345,
|
PP = 12345,
|
||||||
RankHistory = new User.RankHistoryData
|
RankHistory = new User.RankHistoryData
|
||||||
{
|
{
|
||||||
@ -118,7 +118,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
graph.Statistics.Value = new UserStatistics
|
graph.Statistics.Value = new UserStatistics
|
||||||
{
|
{
|
||||||
Ranks = new UserStatistics.UserRanks { Global = 12000 },
|
GlobalRank = 12000,
|
||||||
PP = 12345,
|
PP = 12345,
|
||||||
RankHistory = new User.RankHistoryData
|
RankHistory = new User.RankHistoryData
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,8 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
ProfileOrder = new[] { "me" },
|
ProfileOrder = new[] { "me" },
|
||||||
Statistics = new UserStatistics
|
Statistics = new UserStatistics
|
||||||
{
|
{
|
||||||
Ranks = new UserStatistics.UserRanks { Global = 2148, Country = 1 },
|
GlobalRank = 2148,
|
||||||
|
CountryRank = 1,
|
||||||
PP = 4567.89m,
|
PP = 4567.89m,
|
||||||
Level = new UserStatistics.LevelInfo
|
Level = new UserStatistics.LevelInfo
|
||||||
{
|
{
|
||||||
|
@ -113,11 +113,11 @@ namespace osu.Game.Tournament.Tests
|
|||||||
},
|
},
|
||||||
Players =
|
Players =
|
||||||
{
|
{
|
||||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 12 } } },
|
new User { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 12 } },
|
||||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 16 } } },
|
new User { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 16 } },
|
||||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 20 } } },
|
new User { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 20 } },
|
||||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 24 } } },
|
new User { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 24 } },
|
||||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 30 } } },
|
new User { Username = "Hello", Statistics = new UserStatistics { GlobalRank = 30 } },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -36,7 +36,7 @@ namespace osu.Game.Tournament.Models
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var ranks = Players.Select(p => p.Statistics?.Ranks.Global)
|
var ranks = Players.Select(p => p.Statistics?.GlobalRank)
|
||||||
.Where(i => i.HasValue)
|
.Where(i => i.HasValue)
|
||||||
.Select(i => i.Value)
|
.Select(i => i.Value)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
@ -250,7 +250,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
|||||||
};
|
};
|
||||||
|
|
||||||
foreach (var p in team.Players)
|
foreach (var p in team.Players)
|
||||||
fill.Add(new RowDisplay(p.Username, p.Statistics?.Ranks.Global?.ToString("\\##,0") ?? "-"));
|
fill.Add(new RowDisplay(p.Username, p.Statistics?.GlobalRank?.ToString("\\##,0") ?? "-"));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class RowDisplay : CompositeDrawable
|
internal class RowDisplay : CompositeDrawable
|
||||||
|
@ -150,7 +150,7 @@ namespace osu.Game.Tournament
|
|||||||
{
|
{
|
||||||
foreach (var p in t.Players)
|
foreach (var p in t.Players)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(p.Username) || p.Statistics == null)
|
if (string.IsNullOrEmpty(p.Username) || p.Statistics?.GlobalRank == null)
|
||||||
{
|
{
|
||||||
PopulateUser(p, immediate: true);
|
PopulateUser(p, immediate: true);
|
||||||
addedInfo = true;
|
addedInfo = true;
|
||||||
|
@ -144,8 +144,8 @@ namespace osu.Game.Overlays.Profile.Header
|
|||||||
|
|
||||||
private void updateDisplay(User user)
|
private void updateDisplay(User user)
|
||||||
{
|
{
|
||||||
hiddenDetailGlobal.Content = user?.Statistics?.Ranks.Global?.ToString("\\##,##0") ?? "-";
|
hiddenDetailGlobal.Content = user?.Statistics?.GlobalRank?.ToString("\\##,##0") ?? "-";
|
||||||
hiddenDetailCountry.Content = user?.Statistics?.Ranks.Country?.ToString("\\##,##0") ?? "-";
|
hiddenDetailCountry.Content = user?.Statistics?.CountryRank?.ToString("\\##,##0") ?? "-";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,8 +176,8 @@ namespace osu.Game.Overlays.Profile.Header
|
|||||||
foreach (var scoreRankInfo in scoreRankInfos)
|
foreach (var scoreRankInfo in scoreRankInfos)
|
||||||
scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount[scoreRankInfo.Key] ?? 0;
|
scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount[scoreRankInfo.Key] ?? 0;
|
||||||
|
|
||||||
detailGlobalRank.Content = user?.Statistics?.Ranks.Global?.ToString("\\##,##0") ?? "-";
|
detailGlobalRank.Content = user?.Statistics?.GlobalRank?.ToString("\\##,##0") ?? "-";
|
||||||
detailCountryRank.Content = user?.Statistics?.Ranks.Country?.ToString("\\##,##0") ?? "-";
|
detailCountryRank.Content = user?.Statistics?.CountryRank?.ToString("\\##,##0") ?? "-";
|
||||||
|
|
||||||
rankGraph.Statistics.Value = user?.Statistics;
|
rankGraph.Statistics.Value = user?.Statistics;
|
||||||
}
|
}
|
||||||
|
@ -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.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
@ -35,9 +36,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private RulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
|
private SpriteIcon crown;
|
||||||
|
private OsuSpriteText userRankText;
|
||||||
private ModDisplay userModsDisplay;
|
private ModDisplay userModsDisplay;
|
||||||
private StateDisplay userStateDisplay;
|
private StateDisplay userStateDisplay;
|
||||||
private SpriteIcon crown;
|
|
||||||
|
|
||||||
public ParticipantPanel(MultiplayerRoomUser user)
|
public ParticipantPanel(MultiplayerRoomUser user)
|
||||||
{
|
{
|
||||||
@ -119,12 +121,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
|||||||
Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 18),
|
Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 18),
|
||||||
Text = user?.Username
|
Text = user?.Username
|
||||||
},
|
},
|
||||||
new OsuSpriteText
|
userRankText = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
Font = OsuFont.GetFont(size: 14),
|
Font = OsuFont.GetFont(size: 14),
|
||||||
Text = user?.CurrentModeRank != null ? $"#{user.CurrentModeRank}" : string.Empty
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -162,6 +163,11 @@ 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();
|
||||||
|
|
||||||
|
var currentModeRank = User.User?.RulesetsStatistics?.GetValueOrDefault(ruleset.ShortName)?.GlobalRank;
|
||||||
|
userRankText.Text = currentModeRank != null ? $"#{currentModeRank.Value:N0}" : string.Empty;
|
||||||
|
|
||||||
userStateDisplay.UpdateStatus(User.State, User.BeatmapAvailability);
|
userStateDisplay.UpdateStatus(User.State, User.BeatmapAvailability);
|
||||||
|
|
||||||
if (Room.Host?.Equals(User) == true)
|
if (Room.Host?.Equals(User) == true)
|
||||||
@ -171,11 +177,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
|||||||
|
|
||||||
// If the mods are updated at the end of the frame, the flow container will skip a reflow cycle: https://github.com/ppy/osu-framework/issues/4187
|
// If the mods are updated at the end of the frame, the flow container will skip a reflow cycle: https://github.com/ppy/osu-framework/issues/4187
|
||||||
// This looks particularly jarring here, so re-schedule the update to that start of our frame as a fix.
|
// This looks particularly jarring here, so re-schedule the update to that start of our frame as a fix.
|
||||||
Schedule(() =>
|
Schedule(() => userModsDisplay.Current.Value = User.Mods.Select(m => m.ToMod(ruleset)).ToList());
|
||||||
{
|
|
||||||
var ruleset = rulesets.GetRuleset(Room.Settings.RulesetID).CreateInstance();
|
|
||||||
userModsDisplay.Current.Value = User.Mods.Select(m => m.ToMod(ruleset)).ToList();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MenuItem[] ContextMenuItems
|
public MenuItem[] ContextMenuItems
|
||||||
|
@ -2,10 +2,13 @@
|
|||||||
// 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.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
|
|
||||||
namespace osu.Game.Users
|
namespace osu.Game.Users
|
||||||
{
|
{
|
||||||
@ -178,6 +181,10 @@ namespace osu.Game.Users
|
|||||||
|
|
||||||
private UserStatistics statistics;
|
private UserStatistics statistics;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// User statistics for the requested ruleset (in the case of a <see cref="GetUserRequest"/> response).
|
||||||
|
/// Otherwise empty.
|
||||||
|
/// </summary>
|
||||||
[JsonProperty(@"statistics")]
|
[JsonProperty(@"statistics")]
|
||||||
public UserStatistics Statistics
|
public UserStatistics Statistics
|
||||||
{
|
{
|
||||||
@ -228,14 +235,14 @@ namespace osu.Game.Users
|
|||||||
[JsonProperty("replays_watched_counts")]
|
[JsonProperty("replays_watched_counts")]
|
||||||
public UserHistoryCount[] ReplaysWatchedCounts;
|
public UserHistoryCount[] ReplaysWatchedCounts;
|
||||||
|
|
||||||
public class UserHistoryCount
|
/// <summary>
|
||||||
{
|
/// All user statistics per ruleset's short name (in the case of a <see cref="GetUsersRequest"/> response).
|
||||||
[JsonProperty("start_date")]
|
/// Otherwise empty. Can be altered for testing purposes.
|
||||||
public DateTime Date;
|
/// </summary>
|
||||||
|
// todo: this should likely be moved to a separate UserCompact class at some point.
|
||||||
[JsonProperty("count")]
|
[JsonProperty("statistics_rulesets")]
|
||||||
public long Count;
|
[CanBeNull]
|
||||||
}
|
public Dictionary<string, UserStatistics> RulesetsStatistics { get; set; }
|
||||||
|
|
||||||
public override string ToString() => Username;
|
public override string ToString() => Username;
|
||||||
|
|
||||||
@ -249,6 +256,14 @@ namespace osu.Game.Users
|
|||||||
Id = 0
|
Id = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public bool Equals(User other)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(null, other)) return false;
|
||||||
|
if (ReferenceEquals(this, other)) return true;
|
||||||
|
|
||||||
|
return Id == other.Id;
|
||||||
|
}
|
||||||
|
|
||||||
public enum PlayStyle
|
public enum PlayStyle
|
||||||
{
|
{
|
||||||
[Description("Keyboard")]
|
[Description("Keyboard")]
|
||||||
@ -264,12 +279,13 @@ namespace osu.Game.Users
|
|||||||
Touch,
|
Touch,
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(User other)
|
public class UserHistoryCount
|
||||||
{
|
{
|
||||||
if (ReferenceEquals(null, other)) return false;
|
[JsonProperty("start_date")]
|
||||||
if (ReferenceEquals(this, other)) return true;
|
public DateTime Date;
|
||||||
|
|
||||||
return Id == other.Id;
|
[JsonProperty("count")]
|
||||||
|
public long Count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,17 +26,24 @@ namespace osu.Game.Users
|
|||||||
public int Progress;
|
public int Progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonProperty(@"pp")]
|
[JsonProperty(@"global_rank")]
|
||||||
public decimal? PP;
|
public int? GlobalRank;
|
||||||
|
|
||||||
[JsonProperty(@"pp_rank")] // the API sometimes only returns this value in condensed user responses
|
public int? CountryRank;
|
||||||
private int? rank
|
|
||||||
{
|
|
||||||
set => Ranks.Global = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(@"rank")]
|
[JsonProperty(@"rank")]
|
||||||
public UserRanks Ranks;
|
private UserRanks ranks
|
||||||
|
{
|
||||||
|
// eventually that will also become an own json property instead of reading from a `rank` object.
|
||||||
|
// see https://github.com/ppy/osu-web/blob/cb79bb72186c8f1a25f6a6f5ef315123decb4231/app/Transformers/UserStatisticsTransformer.php#L53.
|
||||||
|
set => CountryRank = value.Country;
|
||||||
|
}
|
||||||
|
|
||||||
|
// populated via User model, as that's where the data currently lives.
|
||||||
|
public RankHistoryData RankHistory;
|
||||||
|
|
||||||
|
[JsonProperty(@"pp")]
|
||||||
|
public decimal? PP;
|
||||||
|
|
||||||
[JsonProperty(@"ranked_score")]
|
[JsonProperty(@"ranked_score")]
|
||||||
public long RankedScore;
|
public long RankedScore;
|
||||||
@ -113,15 +120,12 @@ namespace osu.Game.Users
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct UserRanks
|
#pragma warning disable 649
|
||||||
|
private struct UserRanks
|
||||||
{
|
{
|
||||||
[JsonProperty(@"global")]
|
|
||||||
public int? Global;
|
|
||||||
|
|
||||||
[JsonProperty(@"country")]
|
[JsonProperty(@"country")]
|
||||||
public int? Country;
|
public int? Country;
|
||||||
}
|
}
|
||||||
|
#pragma warning restore 649
|
||||||
public RankHistoryData RankHistory;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user