mirror of
https://github.com/ppy/osu.git
synced 2025-01-18 10:43:22 +08:00
Ensure API starts up with LocalUser
in correct state
I noticed in passing that in a very edge case scenario where the API's `run` thread doesn't run before it is loaded into the game, something could access it and get a guest `LocalUser` when the local user actually has a valid login. Put another way, the `protected HasLogin` could be `true` while `LocalUser` is `Guest`. I think we want to avoid this, so I've moved the initial set of the local user earlier in the initialisation process. If this is controversial in any way, the PR can be closed and we can assume no one is ever going to run into this scenario (or that it doesn't matter enough even if they did).
This commit is contained in:
parent
75d1fab6d0
commit
f6073d4ac0
@ -13,6 +13,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Development;
|
||||
using osu.Framework.Extensions.ExceptionExtensions;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
@ -110,6 +111,9 @@ namespace osu.Game.Online.API
|
||||
|
||||
config.BindWith(OsuSetting.UserOnlineStatus, configStatus);
|
||||
|
||||
// Early call to ensure the local user / "logged in" state is correct immediately.
|
||||
setPlaceholderLocalUser();
|
||||
|
||||
localUser.BindValueChanged(u =>
|
||||
{
|
||||
u.OldValue?.Activity.UnbindFrom(activity);
|
||||
@ -193,7 +197,7 @@ namespace osu.Game.Online.API
|
||||
|
||||
Debug.Assert(HasLogin);
|
||||
|
||||
// Ensure that we are in an online state. If not, attempt a connect.
|
||||
// Ensure that we are in an online state. If not, attempt to connect.
|
||||
if (state.Value != APIState.Online)
|
||||
{
|
||||
attemptConnect();
|
||||
@ -247,17 +251,7 @@ namespace osu.Game.Online.API
|
||||
/// <returns>Whether the connection attempt was successful.</returns>
|
||||
private void attemptConnect()
|
||||
{
|
||||
if (localUser.IsDefault)
|
||||
{
|
||||
// Show a placeholder user if saved credentials are available.
|
||||
// This is useful for storing local scores and showing a placeholder username after starting the game,
|
||||
// until a valid connection has been established.
|
||||
setLocalUser(new APIUser
|
||||
{
|
||||
Username = ProvidedUsername,
|
||||
Status = { Value = configStatus.Value ?? UserStatus.Online }
|
||||
});
|
||||
}
|
||||
Scheduler.Add(setPlaceholderLocalUser, false);
|
||||
|
||||
// save the username at this point, if the user requested for it to be.
|
||||
config.SetValue(OsuSetting.Username, config.Get<bool>(OsuSetting.SaveUsername) ? ProvidedUsername : string.Empty);
|
||||
@ -339,9 +333,11 @@ namespace osu.Game.Online.API
|
||||
|
||||
userReq.Success += me =>
|
||||
{
|
||||
Debug.Assert(ThreadSafety.IsUpdateThread);
|
||||
|
||||
me.Status.Value = configStatus.Value ?? UserStatus.Online;
|
||||
|
||||
setLocalUser(me);
|
||||
localUser.Value = me;
|
||||
|
||||
state.Value = me.SessionVerified ? APIState.Online : APIState.RequiresSecondFactorAuth;
|
||||
failureCount = 0;
|
||||
@ -366,6 +362,23 @@ namespace osu.Game.Online.API
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show a placeholder user if saved credentials are available.
|
||||
/// This is useful for storing local scores and showing a placeholder username after starting the game,
|
||||
/// until a valid connection has been established.
|
||||
/// </summary>
|
||||
private void setPlaceholderLocalUser()
|
||||
{
|
||||
if (!localUser.IsDefault)
|
||||
return;
|
||||
|
||||
localUser.Value = new APIUser
|
||||
{
|
||||
Username = ProvidedUsername,
|
||||
Status = { Value = configStatus.Value ?? UserStatus.Online }
|
||||
};
|
||||
}
|
||||
|
||||
public void Perform(APIRequest request)
|
||||
{
|
||||
try
|
||||
@ -593,7 +606,7 @@ namespace osu.Game.Online.API
|
||||
// Scheduled prior to state change such that the state changed event is invoked with the correct user and their friends present
|
||||
Schedule(() =>
|
||||
{
|
||||
setLocalUser(createGuestUser());
|
||||
localUser.Value = createGuestUser();
|
||||
friends.Clear();
|
||||
});
|
||||
|
||||
@ -619,8 +632,6 @@ namespace osu.Game.Online.API
|
||||
|
||||
private static APIUser createGuestUser() => new GuestUser();
|
||||
|
||||
private void setLocalUser(APIUser user) => Scheduler.Add(() => localUser.Value = user, false);
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
Loading…
Reference in New Issue
Block a user