Skip to content

Commit a8456ce

Browse files
authored
Merge pull request #31513 from smoogipoo/remove-status-from-apiuser
Remove `Status` and `Activity` bindables from `APIUser`
2 parents 88829d5 + 41c603b commit a8456ce

21 files changed

+186
-183
lines changed

osu.Desktop/DiscordRichPresence.cs

+16-25
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,9 @@ internal partial class DiscordRichPresence : Component
5151
[Resolved]
5252
private LocalUserStatisticsProvider statisticsProvider { get; set; } = null!;
5353

54-
[Resolved]
55-
private OsuConfigManager config { get; set; } = null!;
56-
57-
private readonly IBindable<UserStatus?> status = new Bindable<UserStatus?>();
58-
private readonly IBindable<UserActivity> activity = new Bindable<UserActivity>();
59-
private readonly Bindable<DiscordRichPresenceMode> privacyMode = new Bindable<DiscordRichPresenceMode>();
54+
private IBindable<DiscordRichPresenceMode> privacyMode = null!;
55+
private IBindable<UserStatus> userStatus = null!;
56+
private IBindable<UserActivity?> userActivity = null!;
6057

6158
private readonly RichPresence presence = new RichPresence
6259
{
@@ -71,8 +68,12 @@ internal partial class DiscordRichPresence : Component
7168
private IBindable<APIUser>? user;
7269

7370
[BackgroundDependencyLoader]
74-
private void load()
71+
private void load(OsuConfigManager config, SessionStatics session)
7572
{
73+
privacyMode = config.GetBindable<DiscordRichPresenceMode>(OsuSetting.DiscordRichPresence);
74+
userStatus = config.GetBindable<UserStatus>(OsuSetting.UserOnlineStatus);
75+
userActivity = session.GetBindable<UserActivity?>(Static.UserOnlineActivity);
76+
7677
client = new DiscordRpcClient(client_id)
7778
{
7879
// SkipIdenticalPresence allows us to fire SetPresence at any point and leave it to the underlying implementation
@@ -105,21 +106,11 @@ protected override void LoadComplete()
105106
{
106107
base.LoadComplete();
107108

108-
config.BindWith(OsuSetting.DiscordRichPresence, privacyMode);
109-
110109
user = api.LocalUser.GetBoundCopy();
111-
user.BindValueChanged(u =>
112-
{
113-
status.UnbindBindings();
114-
status.BindTo(u.NewValue.Status);
115-
116-
activity.UnbindBindings();
117-
activity.BindTo(u.NewValue.Activity);
118-
}, true);
119110

120111
ruleset.BindValueChanged(_ => schedulePresenceUpdate());
121-
status.BindValueChanged(_ => schedulePresenceUpdate());
122-
activity.BindValueChanged(_ => schedulePresenceUpdate());
112+
userStatus.BindValueChanged(_ => schedulePresenceUpdate());
113+
userActivity.BindValueChanged(_ => schedulePresenceUpdate());
123114
privacyMode.BindValueChanged(_ => schedulePresenceUpdate());
124115

125116
multiplayerClient.RoomUpdated += onRoomUpdated;
@@ -151,13 +142,13 @@ private void schedulePresenceUpdate()
151142
if (!client.IsInitialized)
152143
return;
153144

154-
if (status.Value == UserStatus.Offline || privacyMode.Value == DiscordRichPresenceMode.Off)
145+
if (!api.IsLoggedIn || userStatus.Value == UserStatus.Offline || privacyMode.Value == DiscordRichPresenceMode.Off)
155146
{
156147
client.ClearPresence();
157148
return;
158149
}
159150

160-
bool hideIdentifiableInformation = privacyMode.Value == DiscordRichPresenceMode.Limited || status.Value == UserStatus.DoNotDisturb;
151+
bool hideIdentifiableInformation = privacyMode.Value == DiscordRichPresenceMode.Limited || userStatus.Value == UserStatus.DoNotDisturb;
161152

162153
updatePresence(hideIdentifiableInformation);
163154
client.SetPresence(presence);
@@ -170,12 +161,12 @@ private void updatePresence(bool hideIdentifiableInformation)
170161
return;
171162

172163
// user activity
173-
if (activity.Value != null)
164+
if (userActivity.Value != null)
174165
{
175-
presence.State = clampLength(activity.Value.GetStatus(hideIdentifiableInformation));
176-
presence.Details = clampLength(activity.Value.GetDetails(hideIdentifiableInformation) ?? string.Empty);
166+
presence.State = clampLength(userActivity.Value.GetStatus(hideIdentifiableInformation));
167+
presence.Details = clampLength(userActivity.Value.GetDetails(hideIdentifiableInformation) ?? string.Empty);
177168

178-
if (activity.Value.GetBeatmapID(hideIdentifiableInformation) is int beatmapId && beatmapId > 0)
169+
if (userActivity.Value.GetBeatmapID(hideIdentifiableInformation) is int beatmapId && beatmapId > 0)
179170
{
180171
presence.Buttons = new[]
181172
{

osu.Game.Tests/Visual/Menus/TestSceneLoginOverlay.cs

+14-13
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ public partial class TestSceneLoginOverlay : OsuManualInputManagerTestScene
2929
private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
3030

3131
private LoginOverlay loginOverlay = null!;
32-
33-
[Resolved]
34-
private OsuConfigManager configManager { get; set; } = null!;
32+
private OsuConfigManager localConfig = null!;
3533

3634
[Cached(typeof(LocalUserStatisticsProvider))]
3735
private readonly TestSceneUserPanel.TestUserStatisticsProvider statisticsProvider = new TestSceneUserPanel.TestUserStatisticsProvider();
3836

3937
[BackgroundDependencyLoader]
4038
private void load()
4139
{
40+
Dependencies.Cache(localConfig = new OsuConfigManager(LocalStorage));
41+
4242
Child = loginOverlay = new LoginOverlay
4343
{
4444
Anchor = Anchor.Centre,
@@ -49,6 +49,7 @@ private void load()
4949
[SetUpSteps]
5050
public void SetUpSteps()
5151
{
52+
AddStep("reset online state", () => localConfig.SetValue(OsuSetting.UserOnlineStatus, UserStatus.Online));
5253
AddStep("show login overlay", () => loginOverlay.Show());
5354
}
5455

@@ -89,7 +90,7 @@ public void TestLoginSuccess()
8990
AddStep("clear handler", () => dummyAPI.HandleRequest = null);
9091

9192
assertDropdownState(UserAction.Online);
92-
AddStep("change user state", () => dummyAPI.LocalUser.Value.Status.Value = UserStatus.DoNotDisturb);
93+
AddStep("change user state", () => localConfig.SetValue(OsuSetting.UserOnlineStatus, UserStatus.DoNotDisturb));
9394
assertDropdownState(UserAction.DoNotDisturb);
9495
}
9596

@@ -188,31 +189,31 @@ public void TestClickingOnFlagClosesOverlay()
188189
public void TestUncheckingRememberUsernameClearsIt()
189190
{
190191
AddStep("logout", () => API.Logout());
191-
AddStep("set username", () => configManager.SetValue(OsuSetting.Username, "test_user"));
192-
AddStep("set remember password", () => configManager.SetValue(OsuSetting.SavePassword, true));
192+
AddStep("set username", () => localConfig.SetValue(OsuSetting.Username, "test_user"));
193+
AddStep("set remember password", () => localConfig.SetValue(OsuSetting.SavePassword, true));
193194
AddStep("uncheck remember username", () =>
194195
{
195196
InputManager.MoveMouseTo(loginOverlay.ChildrenOfType<SettingsCheckbox>().First());
196197
InputManager.Click(MouseButton.Left);
197198
});
198-
AddAssert("remember username off", () => configManager.Get<bool>(OsuSetting.SaveUsername), () => Is.False);
199-
AddAssert("remember password off", () => configManager.Get<bool>(OsuSetting.SavePassword), () => Is.False);
200-
AddAssert("username cleared", () => configManager.Get<string>(OsuSetting.Username), () => Is.Empty);
199+
AddAssert("remember username off", () => localConfig.Get<bool>(OsuSetting.SaveUsername), () => Is.False);
200+
AddAssert("remember password off", () => localConfig.Get<bool>(OsuSetting.SavePassword), () => Is.False);
201+
AddAssert("username cleared", () => localConfig.Get<string>(OsuSetting.Username), () => Is.Empty);
201202
}
202203

203204
[Test]
204205
public void TestUncheckingRememberPasswordClearsToken()
205206
{
206207
AddStep("logout", () => API.Logout());
207-
AddStep("set token", () => configManager.SetValue(OsuSetting.Token, "test_token"));
208-
AddStep("set remember password", () => configManager.SetValue(OsuSetting.SavePassword, true));
208+
AddStep("set token", () => localConfig.SetValue(OsuSetting.Token, "test_token"));
209+
AddStep("set remember password", () => localConfig.SetValue(OsuSetting.SavePassword, true));
209210
AddStep("uncheck remember token", () =>
210211
{
211212
InputManager.MoveMouseTo(loginOverlay.ChildrenOfType<SettingsCheckbox>().Last());
212213
InputManager.Click(MouseButton.Left);
213214
});
214-
AddAssert("remember password off", () => configManager.Get<bool>(OsuSetting.SavePassword), () => Is.False);
215-
AddAssert("token cleared", () => configManager.Get<string>(OsuSetting.Token), () => Is.Empty);
215+
AddAssert("remember password off", () => localConfig.Get<bool>(OsuSetting.SavePassword), () => Is.False);
216+
AddAssert("token cleared", () => localConfig.Get<string>(OsuSetting.Token), () => Is.Empty);
216217
}
217218
}
218219
}

osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs

+13-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
using osu.Framework.Graphics;
99
using osu.Framework.Testing;
1010
using osu.Game.Beatmaps;
11-
using osu.Game.Online.API;
11+
using osu.Game.Configuration;
1212
using osu.Game.Online.Chat;
1313
using osu.Game.Online.Rooms;
1414
using osu.Game.Rulesets.Mods;
@@ -23,17 +23,23 @@ public partial class TestSceneNowPlayingCommand : OsuTestScene
2323
[Cached(typeof(IChannelPostTarget))]
2424
private PostTarget postTarget { get; set; }
2525

26-
private DummyAPIAccess api => (DummyAPIAccess)API;
26+
private SessionStatics session = null!;
2727

2828
public TestSceneNowPlayingCommand()
2929
{
3030
Add(postTarget = new PostTarget());
3131
}
3232

33+
[BackgroundDependencyLoader]
34+
private void load()
35+
{
36+
Dependencies.Cache(session = new SessionStatics());
37+
}
38+
3339
[Test]
3440
public void TestGenericActivity()
3541
{
36-
AddStep("Set activity", () => api.Activity.Value = new UserActivity.InLobby(new Room()));
42+
AddStep("Set activity", () => session.SetValue<UserActivity>(Static.UserOnlineActivity, new UserActivity.InLobby(new Room())));
3743

3844
AddStep("Run command", () => Add(new NowPlayingCommand(new Channel())));
3945

@@ -43,7 +49,7 @@ public void TestGenericActivity()
4349
[Test]
4450
public void TestEditActivity()
4551
{
46-
AddStep("Set activity", () => api.Activity.Value = new UserActivity.EditingBeatmap(new BeatmapInfo()));
52+
AddStep("Set activity", () => session.SetValue<UserActivity>(Static.UserOnlineActivity, new UserActivity.EditingBeatmap(new BeatmapInfo())));
4753

4854
AddStep("Run command", () => Add(new NowPlayingCommand(new Channel())));
4955

@@ -53,7 +59,7 @@ public void TestEditActivity()
5359
[Test]
5460
public void TestPlayActivity()
5561
{
56-
AddStep("Set activity", () => api.Activity.Value = new UserActivity.InSoloGame(new BeatmapInfo(), new OsuRuleset().RulesetInfo));
62+
AddStep("Set activity", () => session.SetValue<UserActivity>(Static.UserOnlineActivity, new UserActivity.InSoloGame(new BeatmapInfo(), new OsuRuleset().RulesetInfo)));
5763

5864
AddStep("Run command", () => Add(new NowPlayingCommand(new Channel())));
5965

@@ -64,7 +70,7 @@ public void TestPlayActivity()
6470
[TestCase(false)]
6571
public void TestLinkPresence(bool hasOnlineId)
6672
{
67-
AddStep("Set activity", () => api.Activity.Value = new UserActivity.InLobby(new Room()));
73+
AddStep("Set activity", () => session.SetValue<UserActivity>(Static.UserOnlineActivity, new UserActivity.InLobby(new Room())));
6874

6975
AddStep("Set beatmap", () => Beatmap.Value = new DummyWorkingBeatmap(Audio, null)
7076
{
@@ -82,7 +88,7 @@ public void TestLinkPresence(bool hasOnlineId)
8288
[Test]
8389
public void TestModPresence()
8490
{
85-
AddStep("Set activity", () => api.Activity.Value = new UserActivity.InSoloGame(new BeatmapInfo(), new OsuRuleset().RulesetInfo));
91+
AddStep("Set activity", () => session.SetValue<UserActivity>(Static.UserOnlineActivity, new UserActivity.InSoloGame(new BeatmapInfo(), new OsuRuleset().RulesetInfo)));
8692

8793
AddStep("Add Hidden mod", () => SelectedMods.Value = new[] { Ruleset.Value.CreateInstance().CreateMod<ModHidden>() });
8894

osu.Game.Tests/Visual/Online/TestSceneUserClickableAvatar.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,7 @@ private Drawable generateUser(string username, int id, CountryCode countryCode,
6262
CountryCode = countryCode,
6363
CoverUrl = cover,
6464
Colour = color ?? "000000",
65-
Status =
66-
{
67-
Value = UserStatus.Online
68-
},
65+
IsOnline = true
6966
};
7067

7168
return new ClickableAvatar(user, showPanel)

osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public void SetUp() => Schedule(() =>
7676
Id = 3103765,
7777
CountryCode = CountryCode.JP,
7878
CoverUrl = @"https://assets.ppy.sh/user-cover-presets/1/df28696b58541a9e67f6755918951d542d93bdf1da41720fcca2fd2c1ea8cf51.jpeg",
79-
Status = { Value = UserStatus.Online }
79+
IsOnline = true
8080
}) { Width = 300 },
8181
boundPanel1 = new UserGridPanel(new APIUser
8282
{

osu.Game/Configuration/OsuConfigManager.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ protected override void InitialiseDefaults()
209209
SetDefault(OsuSetting.LastProcessedMetadataId, -1);
210210

211211
SetDefault(OsuSetting.ComboColourNormalisationAmount, 0.2f, 0f, 1f, 0.01f);
212-
SetDefault<UserStatus?>(OsuSetting.UserOnlineStatus, null);
212+
SetDefault(OsuSetting.UserOnlineStatus, UserStatus.Online);
213213

214214
SetDefault(OsuSetting.EditorTimelineShowTimingChanges, true);
215215
SetDefault(OsuSetting.EditorTimelineShowBreaks, true);
@@ -440,7 +440,12 @@ public enum OsuSetting
440440
EditorShowSpeedChanges,
441441
TouchDisableGameplayTaps,
442442
ModSelectTextSearchStartsActive,
443+
444+
/// <summary>
445+
/// The status for the current user to broadcast to other players.
446+
/// </summary>
443447
UserOnlineStatus,
448+
444449
MultiplayerRoomFilter,
445450
HideCountryFlags,
446451
EditorTimelineShowTimingChanges,

osu.Game/Configuration/SessionStatics.cs

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using osu.Game.Overlays;
1111
using osu.Game.Overlays.Mods;
1212
using osu.Game.Scoring;
13+
using osu.Game.Users;
1314

1415
namespace osu.Game.Configuration
1516
{
@@ -30,6 +31,7 @@ protected override void InitialiseDefaults()
3031
SetDefault(Static.TouchInputActive, RuntimeInfo.IsMobile);
3132
SetDefault<ScoreInfo>(Static.LastLocalUserScore, null);
3233
SetDefault<ScoreInfo>(Static.LastAppliedOffsetScore, null);
34+
SetDefault<UserActivity>(Static.UserOnlineActivity, null);
3335
}
3436

3537
/// <summary>
@@ -92,5 +94,7 @@ public enum Static
9294
/// This is reset when a new challenge is up.
9395
/// </summary>
9496
DailyChallengeIntroPlayed,
97+
98+
UserOnlineActivity,
9599
}
96100
}

osu.Game/Online/API/APIAccess.cs

+4-23
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ public partial class APIAccess : Component, IAPIProvider
6060

6161
public IBindable<APIUser> LocalUser => localUser;
6262
public IBindableList<APIRelation> Friends => friends;
63-
public IBindable<UserActivity> Activity => activity;
6463

6564
public INotificationsClient NotificationsClient { get; }
6665

@@ -70,15 +69,10 @@ public partial class APIAccess : Component, IAPIProvider
7069

7170
private BindableList<APIRelation> friends { get; } = new BindableList<APIRelation>();
7271

73-
private Bindable<UserActivity> activity { get; } = new Bindable<UserActivity>();
74-
75-
private Bindable<UserStatus?> configStatus { get; } = new Bindable<UserStatus?>();
76-
private Bindable<UserStatus?> localUserStatus { get; } = new Bindable<UserStatus?>();
77-
7872
protected bool HasLogin => authentication.Token.Value != null || (!string.IsNullOrEmpty(ProvidedUsername) && !string.IsNullOrEmpty(password));
7973

74+
private readonly Bindable<UserStatus> configStatus = new Bindable<UserStatus>();
8075
private readonly CancellationTokenSource cancellationToken = new CancellationTokenSource();
81-
8276
private readonly Logger log;
8377

8478
public APIAccess(OsuGameBase game, OsuConfigManager config, EndpointConfiguration endpointConfiguration, string versionHash)
@@ -121,17 +115,6 @@ public APIAccess(OsuGameBase game, OsuConfigManager config, EndpointConfiguratio
121115
state.Value = APIState.Connecting;
122116
}
123117

124-
localUser.BindValueChanged(u =>
125-
{
126-
u.OldValue?.Activity.UnbindFrom(activity);
127-
u.NewValue.Activity.BindTo(activity);
128-
129-
u.OldValue?.Status.UnbindFrom(localUserStatus);
130-
u.NewValue.Status.BindTo(localUserStatus);
131-
}, true);
132-
133-
localUserStatus.BindTo(configStatus);
134-
135118
var thread = new Thread(run)
136119
{
137120
Name = "APIAccess",
@@ -342,10 +325,7 @@ private void attemptConnect()
342325
{
343326
Debug.Assert(ThreadSafety.IsUpdateThread);
344327

345-
me.Status.Value = configStatus.Value ?? UserStatus.Online;
346-
347328
localUser.Value = me;
348-
349329
state.Value = me.SessionVerified ? APIState.Online : APIState.RequiresSecondFactorAuth;
350330
failureCount = 0;
351331
};
@@ -381,8 +361,7 @@ private void setPlaceholderLocalUser()
381361

382362
localUser.Value = new APIUser
383363
{
384-
Username = ProvidedUsername,
385-
Status = { Value = configStatus.Value ?? UserStatus.Online }
364+
Username = ProvidedUsername
386365
};
387366
}
388367

@@ -608,6 +587,8 @@ public void Logout()
608587
password = null;
609588
SecondFactorCode = null;
610589
authentication.Clear();
590+
591+
// Reset the status to be broadcast on the next login, in case multiple players share the same system.
611592
configStatus.Value = UserStatus.Online;
612593

613594
// Scheduled prior to state change such that the state changed event is invoked with the correct user and their friends present

0 commit comments

Comments
 (0)