| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- using LibHac;
- using LibHac.Fs;
- using LibHac.Fs.Shim;
- using Ryujinx.Common;
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Linq;
- namespace Ryujinx.HLE.HOS.Services.Account.Acc
- {
- public class AccountManager
- {
- public static readonly UserId DefaultUserId = new UserId("00000000000000010000000000000000");
- private readonly AccountSaveDataManager _accountSaveDataManager;
- // Todo: The account service doesn't have the permissions to delete save data. Qlaunch takes care of deleting
- // save data, so we're currently passing a client with full permissions. Consider moving save data deletion
- // outside of the AccountManager.
- private readonly HorizonClient _horizonClient;
- private ConcurrentDictionary<string, UserProfile> _profiles;
- public UserProfile LastOpenedUser { get; private set; }
- public AccountManager(HorizonClient horizonClient)
- {
- _horizonClient = horizonClient;
- _profiles = new ConcurrentDictionary<string, UserProfile>();
- _accountSaveDataManager = new AccountSaveDataManager(_profiles);
- if (!_profiles.TryGetValue(DefaultUserId.ToString(), out _))
- {
- byte[] defaultUserImage = EmbeddedResources.Read("Ryujinx.HLE/HOS/Services/Account/Acc/DefaultUserImage.jpg");
- AddUser("RyuPlayer", defaultUserImage, DefaultUserId);
- OpenUser(DefaultUserId);
- }
- else
- {
- OpenUser(_accountSaveDataManager.LastOpened);
- }
- }
- public void AddUser(string name, byte[] image, UserId userId = new UserId())
- {
- if (userId.IsNull)
- {
- userId = new UserId(Guid.NewGuid().ToString().Replace("-", ""));
- }
- UserProfile profile = new UserProfile(userId, name, image);
- _profiles.AddOrUpdate(userId.ToString(), profile, (key, old) => profile);
- _accountSaveDataManager.Save(_profiles);
- }
- public void OpenUser(UserId userId)
- {
- if (_profiles.TryGetValue(userId.ToString(), out UserProfile profile))
- {
- // TODO: Support multiple open users ?
- foreach (UserProfile userProfile in GetAllUsers())
- {
- if (userProfile == LastOpenedUser)
- {
- userProfile.AccountState = AccountState.Closed;
- break;
- }
- }
- (LastOpenedUser = profile).AccountState = AccountState.Open;
- _accountSaveDataManager.LastOpened = userId;
- }
- _accountSaveDataManager.Save(_profiles);
- }
- public void CloseUser(UserId userId)
- {
- if (_profiles.TryGetValue(userId.ToString(), out UserProfile profile))
- {
- profile.AccountState = AccountState.Closed;
- }
- _accountSaveDataManager.Save(_profiles);
- }
- public void OpenUserOnlinePlay(UserId userId)
- {
- if (_profiles.TryGetValue(userId.ToString(), out UserProfile profile))
- {
- // TODO: Support multiple open online users ?
- foreach (UserProfile userProfile in GetAllUsers())
- {
- if (userProfile == LastOpenedUser)
- {
- userProfile.OnlinePlayState = AccountState.Closed;
- break;
- }
- }
- profile.OnlinePlayState = AccountState.Open;
- }
- _accountSaveDataManager.Save(_profiles);
- }
- public void CloseUserOnlinePlay(UserId userId)
- {
- if (_profiles.TryGetValue(userId.ToString(), out UserProfile profile))
- {
- profile.OnlinePlayState = AccountState.Closed;
- }
- _accountSaveDataManager.Save(_profiles);
- }
- public void SetUserImage(UserId userId, byte[] image)
- {
- foreach (UserProfile userProfile in GetAllUsers())
- {
- if (userProfile.UserId == userId)
- {
- userProfile.Image = image;
- break;
- }
- }
- _accountSaveDataManager.Save(_profiles);
- }
- public void SetUserName(UserId userId, string name)
- {
- foreach (UserProfile userProfile in GetAllUsers())
- {
- if (userProfile.UserId == userId)
- {
- userProfile.Name = name;
- break;
- }
- }
- _accountSaveDataManager.Save(_profiles);
- }
- public void DeleteUser(UserId userId)
- {
- DeleteSaveData(userId);
- _profiles.Remove(userId.ToString(), out _);
- OpenUser(DefaultUserId);
- _accountSaveDataManager.Save(_profiles);
- }
- private void DeleteSaveData(UserId userId)
- {
- SaveDataFilter saveDataFilter = new SaveDataFilter();
- saveDataFilter.SetUserId(new LibHac.Fs.UserId((ulong)userId.High, (ulong)userId.Low));
- _horizonClient.Fs.OpenSaveDataIterator(out SaveDataIterator saveDataIterator, SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
- Span<SaveDataInfo> saveDataInfo = stackalloc SaveDataInfo[10];
- while (true)
- {
- saveDataIterator.ReadSaveDataInfo(out long readCount, saveDataInfo).ThrowIfFailure();
- if (readCount == 0)
- {
- break;
- }
- for (int i = 0; i < readCount; i++)
- {
- _horizonClient.Fs.DeleteSaveData(SaveDataSpaceId.User, saveDataInfo[i].SaveDataId).ThrowIfFailure();
- }
- }
- }
- internal int GetUserCount()
- {
- return _profiles.Count;
- }
- internal bool TryGetUser(UserId userId, out UserProfile profile)
- {
- return _profiles.TryGetValue(userId.ToString(), out profile);
- }
- public IEnumerable<UserProfile> GetAllUsers()
- {
- return _profiles.Values;
- }
- internal IEnumerable<UserProfile> GetOpenedUsers()
- {
- return _profiles.Values.Where(x => x.AccountState == AccountState.Open);
- }
- internal UserProfile GetFirst()
- {
- return _profiles.First().Value;
- }
- }
- }
|